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 079da354db3473b56eb938ca53a2cb0804ea9c8c 139 lines 3.3 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 21int printk(const char *fmt, ...); 22 23struct semaphore { 24 atomic_t count; 25 atomic_t waking; 26 wait_queue_head_t wait; 27}; 28 29#define __SEMAPHORE_INITIALIZER(name, n) \ 30{ \ 31 .count = ATOMIC_INIT(n), \ 32 .waking = ATOMIC_INIT(0), \ 33 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 34} 35 36#define __MUTEX_INITIALIZER(name) \ 37 __SEMAPHORE_INITIALIZER(name,1) 38 39#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 40 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 41 42#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 43#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 44 45extern inline void sema_init(struct semaphore *sem, int val) 46{ 47 *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 48} 49 50extern inline void init_MUTEX (struct semaphore *sem) 51{ 52 sema_init(sem, 1); 53} 54 55extern inline void init_MUTEX_LOCKED (struct semaphore *sem) 56{ 57 sema_init(sem, 0); 58} 59 60extern void __down(struct semaphore * sem); 61extern int __down_interruptible(struct semaphore * sem); 62extern int __down_trylock(struct semaphore * sem); 63extern void __up(struct semaphore * sem); 64 65/* notice - we probably can do cli/sti here instead of saving */ 66 67extern inline void down(struct semaphore * sem) 68{ 69 unsigned long flags; 70 int failed; 71 72 might_sleep(); 73 74 /* atomically decrement the semaphores count, and if its negative, we wait */ 75 cris_atomic_save(sem, flags); 76 failed = --(sem->count.counter) < 0; 77 cris_atomic_restore(sem, flags); 78 if(failed) { 79 __down(sem); 80 } 81} 82 83/* 84 * This version waits in interruptible state so that the waiting 85 * process can be killed. The down_interruptible routine 86 * returns negative for signalled and zero for semaphore acquired. 87 */ 88 89extern inline int down_interruptible(struct semaphore * sem) 90{ 91 unsigned long flags; 92 int failed; 93 94 might_sleep(); 95 96 /* atomically decrement the semaphores count, and if its negative, we wait */ 97 cris_atomic_save(sem, flags); 98 failed = --(sem->count.counter) < 0; 99 cris_atomic_restore(sem, flags); 100 if(failed) 101 failed = __down_interruptible(sem); 102 return(failed); 103} 104 105extern inline int down_trylock(struct semaphore * sem) 106{ 107 unsigned long flags; 108 int failed; 109 110 cris_atomic_save(sem, flags); 111 failed = --(sem->count.counter) < 0; 112 cris_atomic_restore(sem, flags); 113 if(failed) 114 failed = __down_trylock(sem); 115 return(failed); 116 117} 118 119/* 120 * Note! This is subtle. We jump to wake people up only if 121 * the semaphore was negative (== somebody was waiting on it). 122 * The default case (no contention) will result in NO 123 * jumps for both down() and up(). 124 */ 125extern inline void up(struct semaphore * sem) 126{ 127 unsigned long flags; 128 int wakeup; 129 130 /* atomically increment the semaphores count, and if it was negative, we wake people */ 131 cris_atomic_save(sem, flags); 132 wakeup = ++(sem->count.counter) <= 0; 133 cris_atomic_restore(sem, flags); 134 if(wakeup) { 135 __up(sem); 136 } 137} 138 139#endif