]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/util/spinlock.h
Initial checkin from Perforce.
[polintos/scott/priv.git] / include / c++ / util / spinlock.h
1 #ifndef _UTIL_SPINLOCK_H
2 #define _UTIL_SPINLOCK_H
3
4 // There are two basic lock types: Lock and SpinLock. A thread that
5 // blocks on a Lock may sleep until it obtains the lock.  In kernel code,
6 // a thread that blocks on a SpinLock will not sleep, but will run a busy
7 // loop until the lock is freed.  In userspace code, a SpinLock behaves
8 // as an ordinary Lock.
9
10 #ifdef _KERNEL
11 #include <kern/spinlock.h>
12 #endif
13
14 namespace Lock {
15 #ifndef _KERNEL
16 #error FIXME -- implement locks for userspace
17         struct Lock {
18         };
19
20         typedef Lock SpinLock;
21 #endif
22
23         struct AutoSpinLock {
24                 SpinLock &real_lock;
25         
26                 AutoSpinLock(SpinLock &lock) : real_lock(lock)
27                 {
28                         real_lock.lock();
29                 }
30                 
31                 ~AutoSpinLock()
32                 {
33                         real_lock.unlock();
34                 }
35         };
36
37         struct DroppableAutoSpinLock {
38                 SpinLock &real_lock;
39                 bool dropped;
40                 
41                 DroppableAutoSpinLock(SpinLock &lock) : real_lock(lock)
42                 {
43                         real_lock.lock();
44                         dropped = false;
45                 }
46                 
47                 ~DroppableAutoSpinLock()
48                 {
49                         if (!dropped)
50                                 real_lock.unlock();
51                 }
52                 
53                 void lock()
54                 {
55                         assert(dropped);
56                         real_lock.lock();
57                         dropped = false;
58                 }
59                 
60                 void unlock()
61                 {
62                         assert(!dropped);
63                         dropped = true;
64                         real_lock.unlock();
65                 }
66         };
67
68         struct AutoSpinLockIRQ {
69                 SpinLock &real_lock;
70         
71                 AutoSpinLockIRQ(SpinLock &lock) : real_lock(lock)
72                 {
73                         real_lock.lock_irq();
74                 }
75                 
76                 ~AutoSpinLockIRQ()
77                 {
78                         real_lock.unlock_irq();
79                 }
80         };
81
82         struct DroppableAutoSpinLockIRQ {
83                 SpinLock &real_lock;
84                 bool dropped;
85                 
86                 DroppableAutoSpinLockIRQ(SpinLock &lock) : real_lock(lock)
87                 {
88                         real_lock.lock_irq();
89                         dropped = false;
90                 }
91                 
92                 ~DroppableAutoSpinLockIRQ()
93                 {
94                         if (!dropped)
95                                 real_lock.unlock_irq();
96                 }
97                 
98                 void lock()
99                 {
100                         assert(dropped);
101                         real_lock.lock_irq();
102                         dropped = false;
103                 }
104                 
105                 void unlock()
106                 {
107                         assert(!dropped);
108                         dropped = true;
109                         real_lock.unlock_irq();
110                 }
111         };
112
113         struct AutoSpinLockRecIRQ {
114                 SpinLock &real_lock;
115                 ulong savedirq;
116         
117                 AutoSpinLockRecIRQ(SpinLock &lock) : real_lock(lock)
118                 {
119                         savedirq = real_lock.lock_recirq();
120                 }
121                 
122                 ~AutoSpinLockRecIRQ()
123                 {
124                         real_lock.unlock_recirq(savedirq);
125                 }
126         };
127
128         struct DroppableAutoSpinLockRecIRQ {
129                 SpinLock &real_lock;
130                 ulong savedirq;
131                 bool dropped;
132                 
133                 DroppableAutoSpinLockRecIRQ(SpinLock &lock) : real_lock(lock)
134                 {
135                         savedirq = real_lock.lock_recirq();
136                         dropped = false;
137                 }
138                 
139                 ~DroppableAutoSpinLockRecIRQ()
140                 {
141                         if (!dropped)
142                                 real_lock.unlock_recirq(savedirq);
143                 }
144                 
145                 void lock()
146                 {
147                         assert(dropped);
148                         savedirq = real_lock.lock_recirq();
149                         dropped = false;
150                 }
151                 
152                 void unlock()
153                 {
154                         assert(!dropped);
155                         dropped = true;
156                         real_lock.unlock_recirq(savedirq);
157                 }
158         };
159 }
160
161 #endif