Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at c9a28fa7b9ac19b676deefa0a171ce7df8755c08 133 lines 3.1 kB view raw
1/* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */ 2 3/* On the i386 these are coded in asm, perhaps we should as well. Later.. */ 4 5#ifndef _CRIS_SEMAPHORE_H 6#define _CRIS_SEMAPHORE_H 7 8#define RW_LOCK_BIAS 0x01000000 9 10#include <linux/wait.h> 11#include <linux/spinlock.h> 12#include <linux/rwsem.h> 13 14#include <asm/system.h> 15#include <asm/atomic.h> 16 17/* 18 * CRIS semaphores, implemented in C-only so far. 19 */ 20 21struct semaphore { 22 atomic_t count; 23 atomic_t waking; 24 wait_queue_head_t wait; 25}; 26 27#define __SEMAPHORE_INITIALIZER(name, n) \ 28{ \ 29 .count = ATOMIC_INIT(n), \ 30 .waking = ATOMIC_INIT(0), \ 31 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 32} 33 34#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 35 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 36 37#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 38 39static inline void sema_init(struct semaphore *sem, int val) 40{ 41 *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 42} 43 44static inline void init_MUTEX (struct semaphore *sem) 45{ 46 sema_init(sem, 1); 47} 48 49static inline void init_MUTEX_LOCKED (struct semaphore *sem) 50{ 51 sema_init(sem, 0); 52} 53 54extern void __down(struct semaphore * sem); 55extern int __down_interruptible(struct semaphore * sem); 56extern int __down_trylock(struct semaphore * sem); 57extern void __up(struct semaphore * sem); 58 59/* notice - we probably can do cli/sti here instead of saving */ 60 61static inline void down(struct semaphore * sem) 62{ 63 unsigned long flags; 64 int failed; 65 66 might_sleep(); 67 68 /* atomically decrement the semaphores count, and if its negative, we wait */ 69 cris_atomic_save(sem, flags); 70 failed = --(sem->count.counter) < 0; 71 cris_atomic_restore(sem, flags); 72 if(failed) { 73 __down(sem); 74 } 75} 76 77/* 78 * This version waits in interruptible state so that the waiting 79 * process can be killed. The down_interruptible routine 80 * returns negative for signalled and zero for semaphore acquired. 81 */ 82 83static inline int down_interruptible(struct semaphore * sem) 84{ 85 unsigned long flags; 86 int failed; 87 88 might_sleep(); 89 90 /* atomically decrement the semaphores count, and if its negative, we wait */ 91 cris_atomic_save(sem, flags); 92 failed = --(sem->count.counter) < 0; 93 cris_atomic_restore(sem, flags); 94 if(failed) 95 failed = __down_interruptible(sem); 96 return(failed); 97} 98 99static inline int down_trylock(struct semaphore * sem) 100{ 101 unsigned long flags; 102 int failed; 103 104 cris_atomic_save(sem, flags); 105 failed = --(sem->count.counter) < 0; 106 cris_atomic_restore(sem, flags); 107 if(failed) 108 failed = __down_trylock(sem); 109 return(failed); 110 111} 112 113/* 114 * Note! This is subtle. We jump to wake people up only if 115 * the semaphore was negative (== somebody was waiting on it). 116 * The default case (no contention) will result in NO 117 * jumps for both down() and up(). 118 */ 119static inline void up(struct semaphore * sem) 120{ 121 unsigned long flags; 122 int wakeup; 123 124 /* atomically increment the semaphores count, and if it was negative, we wake people */ 125 cris_atomic_save(sem, flags); 126 wakeup = ++(sem->count.counter) <= 0; 127 cris_atomic_restore(sem, flags); 128 if(wakeup) { 129 __up(sem); 130 } 131} 132 133#endif