]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/lib/libk/lock_guard.cpp
9a1fb99032d6c693f23b445edb7699e222ba48fc
[l4.git] / kernel / fiasco / src / lib / libk / lock_guard.cpp
1 INTERFACE:
2
3 // 
4 // Lock_guard: a guard object using a lock such as helping_lock_t
5 // 
6 template<typename LOCK>
7 class Lock_guard
8 {
9   LOCK *_lock;
10   typename LOCK::Status _state;
11 };
12
13 template< typename LOCK>
14 class Lock_guard_2
15 {
16   LOCK *_l1, *_l2;
17   typename LOCK::Status _state1, _state2;
18 };
19
20 IMPLEMENTATION:
21
22 PUBLIC template<typename LOCK>
23 inline
24 Lock_guard<LOCK>::Lock_guard()
25   : _lock(0)
26 #ifndef NDEBUG
27     , _state(LOCK::Invalid) // silence GCC warning
28 #endif
29 {}
30
31 PUBLIC template<typename LOCK>
32 inline
33 Lock_guard<LOCK>::Lock_guard(LOCK *l)
34   : _lock(l)
35 {
36   _state = _lock->test_and_set();
37 }
38
39 PUBLIC template<typename LOCK>
40 inline
41 bool
42 Lock_guard<LOCK>::lock(LOCK *l)
43 {
44   _lock = l;
45   _state = l->test_and_set();
46   switch (_state)
47     {
48     case LOCK::Locked:
49       return true;
50     case LOCK::Not_locked:
51       _lock = l;                        // Was not locked -- unlock.
52       return true;
53     default:
54       return false; // Error case -- lock not existent
55     }
56 }
57
58 PUBLIC template<typename LOCK>
59 inline
60 void
61 Lock_guard<LOCK>::release()
62 {
63   if (_lock)
64     {
65       _lock->set(_state);
66       _lock = 0;
67     }
68 }
69
70 PUBLIC template<typename LOCK>
71 inline
72 Lock_guard<LOCK>::~Lock_guard()
73 {
74   if (_lock)
75     _lock->set(_state);
76 }
77
78 PUBLIC template<typename LOCK>
79 inline
80 bool
81 Lock_guard<LOCK>::was_set(void)
82 {
83   return _state; //!_lock;
84 }
85
86 PUBLIC template<typename LOCK>
87 inline
88 Lock_guard_2<LOCK>::Lock_guard_2()
89   : _l1(0), _l2(0)
90 {}
91
92 PUBLIC template<typename LOCK>
93 inline
94 Lock_guard_2<LOCK>::Lock_guard_2(LOCK *l1, LOCK *l2)
95   : _l1(l1 < l2 ? l1 : l2), _l2(l1 < l2 ? l2 : l1)
96 {
97   _state1 = _l1->test_and_set();
98   if (_l1 == _l2)
99     _l2 = 0;
100   else
101     _state2 = _l2->test_and_set();
102 }
103
104
105 PUBLIC template<typename LOCK>
106 inline
107 bool
108 Lock_guard_2<LOCK>::lock(LOCK *l1, LOCK *l2)
109 {
110   _l1 = l1 < l2 ? l1 : l2;
111   _l2 = l1 < l2 ? l2 : l1;
112   if ((_state1 = _l1->test_and_set()) == LOCK::Invalid)
113     {
114       _l1 = _l2 = 0;
115       return false;
116     }
117
118   if (_l1 == _l2)
119     _l2 = 0;
120   else if ((_state2 = _l2->test_and_set()) == LOCK::Invalid)
121     {
122       _l2 = 0;
123       return false;
124     }
125
126   return true;
127 }
128
129 PUBLIC template<typename LOCK>
130 inline
131 Lock_guard_2<LOCK>::~Lock_guard_2()
132 {
133   if (_l2)
134     _l2->set(_state2);
135
136   if (_l1)
137     _l1->set(_state1);
138 }