diff options
Diffstat (limited to 'include/asm-i386/semaphore.h')
-rw-r--r-- | include/asm-i386/semaphore.h | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h index ccf69385c..3298aeb13 100644 --- a/include/asm-i386/semaphore.h +++ b/include/asm-i386/semaphore.h @@ -27,15 +27,69 @@ #include <asm/system.h> #include <asm/atomic.h> #include <asm/spinlock.h> +#include <linux/wait.h> struct semaphore { atomic_t count; int waking; - struct wait_queue * wait; + wait_queue_head_t wait; +#if WAITQUEUE_DEBUG + long __magic; +#endif }; -#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL }) +#if WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (int)&(name).__magic +#else +# define __SEM_DEBUG_INIT(name) +#endif + +#define __SEMAPHORE_INITIALIZER(name,count) \ +{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name,1) + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +extern inline void __sema_init (struct semaphore *sem, int val) +{ +/* + * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); + * + * i'd rather use the more flexible initialization above, but sadly + * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. + */ + atomic_set(&sem->count, val); + sem->waking = 0; + init_waitqueue_head(&sem->wait); +#if WAITQUEUE_DEBUG + sem->__magic = (int)&sem->__magic; +#endif +} +#define sema_init(sem,val) \ + do { \ + struct semaphore *__sem = (sem); \ + printk("sema_init called at %s, %d for semaphore 0x%08lx\n", \ + __FILE__, __LINE__, (unsigned long) __sem); \ + __sema_init(__sem, (val)); \ + while(1); + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} asmlinkage void __down_failed(void /* special register calling convention */); asmlinkage int __down_failed_interruptible(void /* params in registers */); @@ -49,8 +103,6 @@ asmlinkage void __up(struct semaphore * sem); extern spinlock_t semaphore_wake_lock; -#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) - /* * This is ugly, but we want the default case to fall through. * "down_failed" is a special asm handler that calls the C @@ -58,6 +110,10 @@ extern spinlock_t semaphore_wake_lock; */ extern inline void down(struct semaphore * sem) { +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic down operation\n\t" #ifdef __SMP__ @@ -79,6 +135,10 @@ extern inline int down_interruptible(struct semaphore * sem) { int result; +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic interruptible down operation\n\t" #ifdef __SMP__ @@ -102,6 +162,10 @@ extern inline int down_trylock(struct semaphore * sem) { int result; +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic interruptible down operation\n\t" #ifdef __SMP__ @@ -129,6 +193,9 @@ extern inline int down_trylock(struct semaphore * sem) */ extern inline void up(struct semaphore * sem) { +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif __asm__ __volatile__( "# atomic up operation\n\t" #ifdef __SMP__ |