Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.20 116 lines 2.8 kB view raw
1#ifndef __ASM_SH_SEMAPHORE_H 2#define __ASM_SH_SEMAPHORE_H 3 4#include <linux/linkage.h> 5 6#ifdef __KERNEL__ 7/* 8 * SMP- and interrupt-safe semaphores. 9 * 10 * (C) Copyright 1996 Linus Torvalds 11 * 12 * SuperH verison by Niibe Yutaka 13 * (Currently no asm implementation but generic C code...) 14 */ 15 16#include <linux/spinlock.h> 17#include <linux/rwsem.h> 18#include <linux/wait.h> 19 20#include <asm/system.h> 21#include <asm/atomic.h> 22 23struct semaphore { 24 atomic_t count; 25 int sleepers; 26 wait_queue_head_t wait; 27}; 28 29#define __SEMAPHORE_INITIALIZER(name, n) \ 30{ \ 31 .count = ATOMIC_INIT(n), \ 32 .sleepers = 0, \ 33 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 34} 35 36#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 37 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 38 39#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 40#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 41 42static inline void sema_init (struct semaphore *sem, int val) 43{ 44/* 45 * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 46 * 47 * i'd rather use the more flexible initialization above, but sadly 48 * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. 49 */ 50 atomic_set(&sem->count, val); 51 sem->sleepers = 0; 52 init_waitqueue_head(&sem->wait); 53} 54 55static inline void init_MUTEX (struct semaphore *sem) 56{ 57 sema_init(sem, 1); 58} 59 60static inline void init_MUTEX_LOCKED (struct semaphore *sem) 61{ 62 sema_init(sem, 0); 63} 64 65#if 0 66asmlinkage void __down_failed(void /* special register calling convention */); 67asmlinkage int __down_failed_interruptible(void /* params in registers */); 68asmlinkage int __down_failed_trylock(void /* params in registers */); 69asmlinkage void __up_wakeup(void /* special register calling convention */); 70#endif 71 72asmlinkage void __down(struct semaphore * sem); 73asmlinkage int __down_interruptible(struct semaphore * sem); 74asmlinkage int __down_trylock(struct semaphore * sem); 75asmlinkage void __up(struct semaphore * sem); 76 77extern spinlock_t semaphore_wake_lock; 78 79static inline void down(struct semaphore * sem) 80{ 81 might_sleep(); 82 if (atomic_dec_return(&sem->count) < 0) 83 __down(sem); 84} 85 86static inline int down_interruptible(struct semaphore * sem) 87{ 88 int ret = 0; 89 90 might_sleep(); 91 if (atomic_dec_return(&sem->count) < 0) 92 ret = __down_interruptible(sem); 93 return ret; 94} 95 96static inline int down_trylock(struct semaphore * sem) 97{ 98 int ret = 0; 99 100 if (atomic_dec_return(&sem->count) < 0) 101 ret = __down_trylock(sem); 102 return ret; 103} 104 105/* 106 * Note! This is subtle. We jump to wake people up only if 107 * the semaphore was negative (== somebody was waiting on it). 108 */ 109static inline void up(struct semaphore * sem) 110{ 111 if (atomic_inc_return(&sem->count) <= 0) 112 __up(sem); 113} 114 115#endif 116#endif /* __ASM_SH_SEMAPHORE_H */