~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-ppc/semaphore.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _PPC_SEMAPHORE_H
  2 #define _PPC_SEMAPHORE_H
  3 
  4 /*
  5  * Swiped from asm-sparc/semaphore.h and modified
  6  * -- Cort (cort@cs.nmt.edu)
  7  *
  8  * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
  9  * -- Ani Joshi (ajoshi@unixbox.com)
 10  */
 11 
 12 #ifdef __KERNEL__
 13 
 14 #include <asm/atomic.h>
 15 #include <asm/system.h>
 16 #include <linux/wait.h>
 17 
 18 struct semaphore {
 19         atomic_t count;
 20         atomic_t waking;
 21         wait_queue_head_t wait;
 22 #if WAITQUEUE_DEBUG
 23         long __magic;
 24 #endif
 25 };
 26 
 27 #if WAITQUEUE_DEBUG
 28 # define __SEM_DEBUG_INIT(name) \
 29                 , (long)&(name).__magic
 30 #else
 31 # define __SEM_DEBUG_INIT(name)
 32 #endif
 33 
 34 #define __SEMAPHORE_INITIALIZER(name,count) \
 35 { ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 36         __SEM_DEBUG_INIT(name) }
 37 
 38 #define __MUTEX_INITIALIZER(name) \
 39         __SEMAPHORE_INITIALIZER(name,1)
 40 
 41 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
 42         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 43 
 44 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 45 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 46 
 47 extern inline void sema_init (struct semaphore *sem, int val)
 48 {
 49         atomic_set(&sem->count, val);
 50         atomic_set(&sem->waking, 0);
 51         init_waitqueue_head(&sem->wait);
 52 #if WAITQUEUE_DEBUG
 53         sem->__magic = (long)&sem->__magic;
 54 #endif
 55 }
 56 
 57 static inline void init_MUTEX (struct semaphore *sem)
 58 {
 59         sema_init(sem, 1);
 60 }
 61 
 62 static inline void init_MUTEX_LOCKED (struct semaphore *sem)
 63 {
 64         sema_init(sem, 0);
 65 }
 66 
 67 extern void __down(struct semaphore * sem);
 68 extern int  __down_interruptible(struct semaphore * sem);
 69 extern int  __down_trylock(struct semaphore * sem);
 70 extern void __up(struct semaphore * sem);
 71 
 72 extern inline void down(struct semaphore * sem)
 73 {
 74         if (atomic_dec_return(&sem->count) >= 0)
 75                 wmb();
 76         else
 77                 __down(sem);
 78 }
 79 
 80 extern inline int down_interruptible(struct semaphore * sem)
 81 {
 82         int ret = 0;
 83 
 84         if (atomic_dec_return(&sem->count) >= 0)
 85                 wmb();
 86         else
 87                 ret = __down_interruptible(sem);
 88         return ret;
 89 }
 90 
 91 extern inline int down_trylock(struct semaphore * sem)
 92 {
 93         int ret = 0;
 94 
 95         if (atomic_dec_return(&sem->count) >= 0)
 96                 wmb();
 97         else
 98                 ret = __down_trylock(sem);
 99         return ret;
100 }
101 
102 extern inline void up(struct semaphore * sem)
103 {
104         mb();
105         if (atomic_inc_return(&sem->count) <= 0)
106                 __up(sem);
107 }       
108 
109 
110 /* RW spinlock-based semaphores */
111 
112 struct rw_semaphore
113 {
114         spinlock_t lock;
115         int rd, wr;
116         wait_queue_head_t wait;
117 #if WAITQUEUE_DEBUG
118         long __magic;
119 #endif
120 };
121 
122 #define __RWSEM_INITIALIZER(name, rd, wr)               \
123 {                                                       \
124         SPIN_LOCK_UNLOCKED,                             \
125         (rd), (wr),                                     \
126         __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)      \
127         __SEM_DEBUG_INIT(name)                          \
128 }
129 
130 #define __DECLARE_RWSEM_GENERIC(name, rd, wr)           \
131         struct rw_semaphore name = __RWSEM_INITIALIZER(name, rd, wr)
132 
133 #define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name, 0, 0)
134 #define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name, 1, 0)
135 #define DECLAER_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name, 0, 1)
136 
137 extern inline void init_rwsem(struct rw_semaphore *sem)
138 {
139         spin_lock_init(&sem->lock);
140         sem->rd = sem->wr = 0;
141         init_waitqueue_head(&sem->wait);
142 #if WAITQUEUE_DEBUG
143         sem->__magic = (long)&sem->__magic;
144 #endif
145 }
146 
147 #ifndef CHECK_MAGIC
148 #define CHECK_MAGIC(x)
149 #endif
150 
151 extern void down_read_failed(struct rw_semaphore *);
152 extern void down_write_failed(struct rw_semaphore *);
153 
154 extern inline void down_read(struct rw_semaphore *sem)
155 {
156         CHECK_MAGIC(sem->__magic);
157 
158         spin_lock_irq(&sem->lock);
159         if (sem->wr)
160                 down_read_failed(sem);
161         sem->rd++;
162         spin_unlock_irq(&sem->lock);
163 }
164 
165 extern inline void down_write(struct rw_semaphore *sem)
166 {
167         CHECK_MAGIC(sem->__magic);
168 
169         spin_lock(&sem->lock);
170         if(sem->rd || sem->wr)
171                 down_write_failed(sem);
172         sem->wr = 1;
173         spin_unlock(&sem->lock);
174 }
175 
176 #define up_read(sem)                                                    \
177         do {                                                            \
178                 unsigned long flags;                                    \
179                                                                         \
180                 CHECK_MAGIC((sem)->__magic);                            \
181                                                                         \
182                 spin_lock_irqsave(&(sem)->lock, flags);                 \
183                 if (!--(sem)->rd && waitqueue_active(&(sem)->wait))     \
184                         wake_up(&(sem)->wait);                          \
185                 spin_unlock_irqrestore(&(sem)->lock, flags);            \
186         } while (0)
187 
188 #define up_write(sem)                                                   \
189         do {                                                            \
190                 unsigned long flags;                                    \
191                                                                         \
192                 CHECK_MAGIC((sem)->__magic);                            \
193                                                                         \
194                 spin_lock_irqsave(&(sem)->lock, flags);                 \
195                 (sem)->wr = 0;                                          \
196                 if (waitqueue_active(&(sem)->wait))                     \
197                         wake_up(&(sem)->wait);                          \
198                 spin_unlock_irqrestore(&(sem)->lock, flags);            \
199         } while (0)
200 
201 
202 #endif /* __KERNEL__ */
203 
204 #endif /* !(_PPC_SEMAPHORE_H) */
205 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.