Rev 5345 | Rev 6102 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5272 | serge | 1 | /* rwsem.h: R/W semaphores implemented using XADD/CMPXCHG for i486+ |
2 | * |
||
3 | * Written by David Howells (dhowells@redhat.com). |
||
4 | * |
||
5 | * Derived from asm-x86/semaphore.h |
||
6 | * |
||
7 | * |
||
8 | * The MSW of the count is the negated number of active writers and waiting |
||
9 | * lockers, and the LSW is the total number of active locks |
||
10 | * |
||
11 | * The lock count is initialized to 0 (no active and no waiting lockers). |
||
12 | * |
||
13 | * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an |
||
14 | * uncontended lock. This can be determined because XADD returns the old value. |
||
15 | * Readers increment by 1 and see a positive value when uncontended, negative |
||
16 | * if there are writers (and maybe) readers waiting (in which case it goes to |
||
17 | * sleep). |
||
18 | * |
||
19 | * The value of WAITING_BIAS supports up to 32766 waiting processes. This can |
||
20 | * be extended to 65534 by manually checking the whole MSW rather than relying |
||
21 | * on the S flag. |
||
22 | * |
||
23 | * The value of ACTIVE_BIAS supports up to 65535 active processes. |
||
24 | * |
||
25 | * This should be totally fair - if anything is waiting, a process that wants a |
||
26 | * lock will go to the back of the queue. When the currently active lock is |
||
27 | * released, if there's a writer at the front of the queue, then that and only |
||
28 | * that will be woken up; if there's a bunch of consequtive readers at the |
||
29 | * front, then they'll all be woken up, but no other readers will be. |
||
30 | */ |
||
31 | |||
32 | #ifndef _ASM_X86_RWSEM_H |
||
33 | #define _ASM_X86_RWSEM_H |
||
34 | |||
35 | #ifndef _LINUX_RWSEM_H |
||
36 | #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" |
||
37 | #endif |
||
38 | |||
39 | #ifdef __KERNEL__ |
||
40 | #include |
||
41 | |||
5345 | serge | 42 | #define FASTCALL __attribute__ ((fastcall)) __attribute__ ((dllimport)) |
5272 | serge | 43 | |
5347 | serge | 44 | void FASTCALL InitRwsem(struct rw_semaphore *sem)__asm__("InitRwsem"); |
5345 | serge | 45 | void FASTCALL DownRead(struct rw_semaphore *sem)__asm__("DownRead"); |
46 | void FASTCALL DownWrite(struct rw_semaphore *sem)__asm__("DownWrite"); |
||
47 | void FASTCALL UpRead(struct rw_semaphore *sem)__asm__("UpRead"); |
||
48 | void FASTCALL UpWrite(struct rw_semaphore *sem)__asm__("UpWrite"); |
||
5272 | serge | 49 | |
5347 | serge | 50 | static inline void __init_rwsem(struct rw_semaphore *sem, const char *name, |
51 | struct lock_class_key *key) |
||
52 | { |
||
53 | InitRwsem(sem); |
||
54 | } |
||
55 | |||
5272 | serge | 56 | /* |
57 | * lock for reading |
||
58 | */ |
||
5347 | serge | 59 | static inline void down_read(struct rw_semaphore *sem) |
5272 | serge | 60 | { |
5345 | serge | 61 | DownRead(sem); |
5272 | serge | 62 | } |
63 | |||
5347 | serge | 64 | static inline void down_write(struct rw_semaphore *sem) |
5272 | serge | 65 | { |
5345 | serge | 66 | DownWrite(sem); |
5272 | serge | 67 | } |
68 | |||
69 | /* |
||
70 | * unlock after reading |
||
71 | */ |
||
5347 | serge | 72 | static inline void up_read(struct rw_semaphore *sem) |
5272 | serge | 73 | { |
5345 | serge | 74 | UpRead(sem); |
5272 | serge | 75 | } |
76 | |||
77 | /* |
||
78 | * unlock after writing |
||
79 | */ |
||
5347 | serge | 80 | static inline void up_write(struct rw_semaphore *sem) |
5272 | serge | 81 | { |
5345 | serge | 82 | UpWrite(sem); |
5272 | serge | 83 | } |
84 | |||
85 | #endif /* __KERNEL__ */ |
||
86 | #endif /* _ASM_X86_RWSEM_H */ |