]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/lib/libk/lock_guard.cpp
update
[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 void
42 Lock_guard<LOCK>::lock(LOCK *l)
43 {
44   _lock = l;
45   _state = l->test_and_set();
46 }
47
48 PUBLIC template<typename LOCK>
49 inline
50 bool
51 Lock_guard<LOCK>::try_lock(LOCK *l)
52 {
53   _state = l->test_and_set();
54   switch (_state)
55     {
56     case LOCK::Locked:
57       return true;
58     case LOCK::Not_locked:
59       _lock = l;                        // Was not locked -- unlock.
60       return true;
61     default:
62       return false; // Error case -- lock not existent
63     }
64 }
65
66 PUBLIC template<typename LOCK>
67 inline
68 void
69 Lock_guard<LOCK>::release()
70 {
71   if (_lock)
72     {
73       _lock->set(_state);
74       _lock = 0;
75     }
76 }
77
78 PUBLIC template<typename LOCK>
79 inline
80 Lock_guard<LOCK>::~Lock_guard()
81 {
82   if (_lock)
83     _lock->set(_state);
84 }
85
86 PUBLIC template<typename LOCK>
87 inline
88 bool
89 Lock_guard<LOCK>::was_set(void)
90 {
91   return _state; //!_lock;
92 }
93
94 PUBLIC template<typename LOCK>
95 inline
96 Lock_guard_2<LOCK>::Lock_guard_2()
97   : _l1(0), _l2(0)
98 {}
99
100 PUBLIC template<typename LOCK>
101 inline
102 Lock_guard_2<LOCK>::Lock_guard_2(LOCK *l1, LOCK *l2)
103   : _l1(l1 < l2 ? l1 : l2), _l2(l1 < l2 ? l2 : l1)
104 {
105   _state1 = _l1->test_and_set();
106   if (_l1 == _l2)
107     _l2 = 0;
108   else
109     _state2 = _l2->test_and_set();
110 }
111
112
113 PUBLIC template<typename LOCK>
114 inline
115 bool
116 Lock_guard_2<LOCK>::lock(LOCK *l1, LOCK *l2)
117 {
118   _l1 = l1 < l2 ? l1 : l2;
119   _l2 = l1 < l2 ? l2 : l1;
120   if ((_state1 = _l1->test_and_set()) == LOCK::Invalid)
121     {
122       _l1 = _l2 = 0;
123       return false;
124     }
125
126   if (_l1 == _l2)
127     _l2 = 0;
128   else if ((_state2 = _l2->test_and_set()) == LOCK::Invalid)
129     {
130       _l2 = 0;
131       return false;
132     }
133
134   return true;
135 }
136
137 PUBLIC template<typename LOCK>
138 inline
139 Lock_guard_2<LOCK>::~Lock_guard_2()
140 {
141   if (_l2)
142     _l2->set(_state2);
143
144   if (_l1)
145     _l1->set(_state1);
146 }