diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-cris/semaphore.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-cris/semaphore.h')
-rw-r--r-- | include/asm-cris/semaphore.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h new file mode 100644 index 000000000000..605aa7eaaaf8 --- /dev/null +++ b/include/asm-cris/semaphore.h | |||
@@ -0,0 +1,142 @@ | |||
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 | |||
21 | int printk(const char *fmt, ...); | ||
22 | |||
23 | struct 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 | |||
45 | extern inline void sema_init(struct semaphore *sem, int val) | ||
46 | { | ||
47 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
48 | } | ||
49 | |||
50 | extern inline void init_MUTEX (struct semaphore *sem) | ||
51 | { | ||
52 | sema_init(sem, 1); | ||
53 | } | ||
54 | |||
55 | extern inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
56 | { | ||
57 | sema_init(sem, 0); | ||
58 | } | ||
59 | |||
60 | extern void __down(struct semaphore * sem); | ||
61 | extern int __down_interruptible(struct semaphore * sem); | ||
62 | extern int __down_trylock(struct semaphore * sem); | ||
63 | extern void __up(struct semaphore * sem); | ||
64 | |||
65 | /* notice - we probably can do cli/sti here instead of saving */ | ||
66 | |||
67 | extern 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 | local_save_flags(flags); | ||
76 | local_irq_disable(); | ||
77 | failed = --(sem->count.counter) < 0; | ||
78 | local_irq_restore(flags); | ||
79 | if(failed) { | ||
80 | __down(sem); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * This version waits in interruptible state so that the waiting | ||
86 | * process can be killed. The down_interruptible routine | ||
87 | * returns negative for signalled and zero for semaphore acquired. | ||
88 | */ | ||
89 | |||
90 | extern inline int down_interruptible(struct semaphore * sem) | ||
91 | { | ||
92 | unsigned long flags; | ||
93 | int failed; | ||
94 | |||
95 | might_sleep(); | ||
96 | |||
97 | /* atomically decrement the semaphores count, and if its negative, we wait */ | ||
98 | local_save_flags(flags); | ||
99 | local_irq_disable(); | ||
100 | failed = --(sem->count.counter) < 0; | ||
101 | local_irq_restore(flags); | ||
102 | if(failed) | ||
103 | failed = __down_interruptible(sem); | ||
104 | return(failed); | ||
105 | } | ||
106 | |||
107 | extern inline int down_trylock(struct semaphore * sem) | ||
108 | { | ||
109 | unsigned long flags; | ||
110 | int failed; | ||
111 | |||
112 | local_save_flags(flags); | ||
113 | local_irq_disable(); | ||
114 | failed = --(sem->count.counter) < 0; | ||
115 | local_irq_restore(flags); | ||
116 | if(failed) | ||
117 | failed = __down_trylock(sem); | ||
118 | return(failed); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Note! This is subtle. We jump to wake people up only if | ||
123 | * the semaphore was negative (== somebody was waiting on it). | ||
124 | * The default case (no contention) will result in NO | ||
125 | * jumps for both down() and up(). | ||
126 | */ | ||
127 | extern inline void up(struct semaphore * sem) | ||
128 | { | ||
129 | unsigned long flags; | ||
130 | int wakeup; | ||
131 | |||
132 | /* atomically increment the semaphores count, and if it was negative, we wake people */ | ||
133 | local_save_flags(flags); | ||
134 | local_irq_disable(); | ||
135 | wakeup = ++(sem->count.counter) <= 0; | ||
136 | local_irq_restore(flags); | ||
137 | if(wakeup) { | ||
138 | __up(sem); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | #endif | ||