]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/include/kern/spinlock.h
Initial checkin from Perforce.
[polintos/scott/priv.git] / kernel / include / kern / spinlock.h
1 #ifndef _KERN_SPINLOCK_H
2 #define _KERN_SPINLOCK_H
3
4 #include <kern/kernel.h>
5 #include <lowlevel/misc.h>
6
7 extern int dying;
8
9 namespace Lock {
10         struct SpinLock {
11                 #if CONF_DEBUG_SPINLOCKS
12                         unsigned long held_at;
13                 #endif  
14         
15                 SpinLock()
16                 {
17                         init();
18                 }
19
20                 void init()
21                 {
22                         // Nothing on UP.  Call arch on SMP.
23                 
24                         #if CONF_DEBUG_SPINLOCKS
25                                 held_at = 0;
26                         #endif
27                 }
28
29                 void lock()
30                 {
31                         // Nothing on UP.  Call arch on SMP.
32
33                         #if CONF_DEBUG_SPINLOCKS
34                                 #if !CONF_SMP
35                                         if (!in_fault && held_at) {
36                                                 in_fault++;
37                                                 printf("Spinlock deadlock, lock %p previously held at 0x%lx\n",
38                                                        this, held_at);
39                                                 in_fault--;
40                                                 BUG();
41                                         }
42                                 #endif
43
44                                 held_at = (ulong)__builtin_return_address(0);
45                         #endif
46                 }
47                 
48                 void unlock()
49                 {
50                         #if CONF_DEBUG_SPINLOCKS
51                                 held_at = 0;
52                         #endif
53
54                         // Nothing on UP.  Call arch on SMP.
55                 }
56
57                 void lock_irq()
58                 {
59                         ll_ints_off();
60                         lock();
61                 }
62
63                 void unlock_irq()
64                 {
65                         unlock();
66                         ll_ints_on();
67                 }
68                 
69                 ulong lock_recirq()
70                 {
71                         unsigned long ret = ll_ints_save_and_off();
72                         lock();
73                         return ret;
74                 }
75                 
76                 void unlock_recirq(ulong savedirq)
77                 {
78                         unlock();
79                         ll_ints_restore(savedirq);
80                 }
81         };
82 }
83
84 #endif