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

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

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

  1 /*
  2  *  include/asm-s390/semaphore.h
  3  *
  4  *  S390 version
  5  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6  *
  7  *  Derived from "include/asm-i386/semaphore.h"
  8  *    (C) Copyright 1996 Linus Torvalds
  9  */
 10 
 11 #ifndef _S390_SEMAPHORE_H
 12 #define _S390_SEMAPHORE_H
 13 
 14 #include <asm/system.h>
 15 #include <asm/atomic.h>
 16 #include <linux/wait.h>
 17 
 18 struct semaphore {
 19         atomic_t count;
 20         int sleepers;
 21         wait_queue_head_t wait;
 22 };
 23 
 24 #define __SEM_DEBUG_INIT(name)
 25 
 26 #define __SEMAPHORE_INITIALIZER(name,count) \
 27 { ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 28         __SEM_DEBUG_INIT(name) }
 29 
 30 #define __MUTEX_INITIALIZER(name) \
 31         __SEMAPHORE_INITIALIZER(name,1)
 32 
 33 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
 34         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 35 
 36 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 37 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 38 
 39 extern inline void sema_init (struct semaphore *sem, int val)
 40 {
 41         *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 42 }
 43 
 44 static inline void init_MUTEX (struct semaphore *sem)
 45 {
 46         sema_init(sem, 1);
 47 }
 48 
 49 static inline void init_MUTEX_LOCKED (struct semaphore *sem)
 50 {
 51         sema_init(sem, 0);
 52 }
 53 
 54 asmlinkage void __down_failed(void /* special register calling convention */);
 55 asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
 56 asmlinkage int  __down_failed_trylock(void  /* params in registers */);
 57 asmlinkage void __up_wakeup(void /* special register calling convention */);
 58 
 59 asmlinkage void __down(struct semaphore * sem);
 60 asmlinkage int  __down_interruptible(struct semaphore * sem);
 61 asmlinkage int  __down_trylock(struct semaphore * sem);
 62 asmlinkage void __up(struct semaphore * sem);
 63 
 64 extern inline void down(struct semaphore * sem)
 65 {
 66         if (atomic_dec_return(&sem->count) < 0)
 67                 __down(sem);
 68 }
 69 
 70 extern inline int down_interruptible(struct semaphore * sem)
 71 {
 72         int ret = 0;
 73 
 74         if (atomic_dec_return(&sem->count) < 0)
 75                 ret = __down_interruptible(sem);
 76         return ret;
 77 }
 78 
 79 extern inline int down_trylock(struct semaphore * sem)
 80 {
 81         int ret = 0;
 82 
 83         if (atomic_dec_return(&sem->count) < 0)
 84                 ret = __down_trylock(sem);
 85         return ret;
 86 }
 87 
 88 extern inline void up(struct semaphore * sem)
 89 {
 90         if (atomic_inc_return(&sem->count) <= 0)
 91                 __up(sem);
 92 }
 93 
 94 /* rw mutexes (should that be mutices? =) -- throw rw
 95  * spinlocks and semaphores together, and this is what we
 96  * end up with...
 97  *
 98  * The lock is initialized to BIAS.  This way, a writer
 99  * subtracts BIAS ands gets 0 for the case of an uncontended
100  * lock.  Readers decrement by 1 and see a positive value
101  * when uncontended, negative if there are writers waiting
102  * (in which case it goes to sleep).
103  *
104  * The value 0x01000000 supports up to 128 processors and
105  * lots of processes.  BIAS must be chosen such that subl'ing
106  * BIAS once per CPU will result in the long remaining
107  * negative.
108  *
109  * In terms of fairness, this should result in the lock
110  * flopping back and forth between readers and writers
111  * under heavy use.
112  *
113  *              -ben
114  */
115 struct rw_semaphore {
116         atomic_t                count;
117         volatile unsigned int   write_bias_granted;
118         volatile unsigned int   read_bias_granted;
119         wait_queue_head_t       wait;
120         wait_queue_head_t       write_bias_wait;
121 };
122 
123 #define RW_LOCK_BIAS             0x01000000
124 
125 #define __RWSEM_DEBUG_INIT      /* */
126 
127 #define __RWSEM_INITIALIZER(name,count) \
128 { ATOMIC_INIT(count), 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
129         __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
130         __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
131 
132 #define __DECLARE_RWSEM_GENERIC(name,count) \
133         struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
134 
135 #define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
136 #define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
137 #define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
138 
139 extern inline void init_rwsem(struct rw_semaphore *sem)
140 {
141         atomic_set(&sem->count, RW_LOCK_BIAS);
142         sem->read_bias_granted = 0;
143         sem->write_bias_granted = 0;
144         init_waitqueue_head(&sem->wait);
145         init_waitqueue_head(&sem->write_bias_wait);
146 }
147 
148 extern void __down_read_failed(int, struct rw_semaphore *);
149 extern void __down_write_failed(int, struct rw_semaphore *);
150 extern void __rwsem_wake(int, struct rw_semaphore *);
151 
152 extern inline void down_read(struct rw_semaphore *sem)
153 {
154         int count;
155         count = atomic_dec_return(&sem->count);
156         if (count < 0)
157                 __down_read_failed(count, sem);
158 }
159 
160 extern inline void down_write(struct rw_semaphore *sem)
161 {
162         int count;
163         count = atomic_add_return (-RW_LOCK_BIAS, &sem->count);
164         if (count < 0)
165                 __down_write_failed(count, sem);
166 }
167 
168 /* When a reader does a release, the only significant
169  * case is when there was a writer waiting, and we've
170  * bumped the count to 0: we must wake the writer up.
171  */
172 extern inline void up_read(struct rw_semaphore *sem)
173 {
174         int count;
175         count = atomic_inc_return(&sem->count);
176         if (count == 0)
177                 __rwsem_wake(count, sem);
178 }
179 
180 /* releasing the writer is easy -- just release it and
181  * wake up any sleepers.
182  */
183 extern inline void up_write(struct rw_semaphore *sem)
184 {
185         int count;
186         count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
187         if (count >= 0 && count < RW_LOCK_BIAS)
188                 __rwsem_wake(count, sem);
189 }
190 
191 #endif
192 

~ [ 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.