|
@@ -60,18 +60,33 @@
|
|
/*
|
|
/*
|
|
* lock for reading
|
|
* lock for reading
|
|
*/
|
|
*/
|
|
|
|
+#define ____down_read(sem, slow_path) \
|
|
|
|
+({ \
|
|
|
|
+ struct rw_semaphore* ret; \
|
|
|
|
+ asm volatile("# beginning down_read\n\t" \
|
|
|
|
+ LOCK_PREFIX _ASM_INC "(%[sem])\n\t" \
|
|
|
|
+ /* adds 0x00000001 */ \
|
|
|
|
+ " jns 1f\n" \
|
|
|
|
+ " call " slow_path "\n" \
|
|
|
|
+ "1:\n\t" \
|
|
|
|
+ "# ending down_read\n\t" \
|
|
|
|
+ : "+m" (sem->count), "=a" (ret), \
|
|
|
|
+ ASM_CALL_CONSTRAINT \
|
|
|
|
+ : [sem] "a" (sem) \
|
|
|
|
+ : "memory", "cc"); \
|
|
|
|
+ ret; \
|
|
|
|
+})
|
|
|
|
+
|
|
static inline void __down_read(struct rw_semaphore *sem)
|
|
static inline void __down_read(struct rw_semaphore *sem)
|
|
{
|
|
{
|
|
- asm volatile("# beginning down_read\n\t"
|
|
|
|
- LOCK_PREFIX _ASM_INC "(%[sem])\n\t"
|
|
|
|
- /* adds 0x00000001 */
|
|
|
|
- " jns 1f\n"
|
|
|
|
- " call call_rwsem_down_read_failed\n"
|
|
|
|
- "1:\n\t"
|
|
|
|
- "# ending down_read\n\t"
|
|
|
|
- : "+m" (sem->count)
|
|
|
|
- : [sem] "a" (sem)
|
|
|
|
- : "memory", "cc");
|
|
|
|
|
|
+ ____down_read(sem, "call_rwsem_down_read_failed");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int __down_read_killable(struct rw_semaphore *sem)
|
|
|
|
+{
|
|
|
|
+ if (IS_ERR(____down_read(sem, "call_rwsem_down_read_failed_killable")))
|
|
|
|
+ return -EINTR;
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|