]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/helping_lock.cpp
update
[l4.git] / kernel / fiasco / src / kern / helping_lock.cpp
1 INTERFACE: 
2
3 #include "lock_guard.h"
4 #include "switch_lock.h"
5
6 #ifdef NO_INSTRUMENT
7 #undef NO_INSTRUMENT
8 #endif
9 #define NO_INSTRUMENT __attribute__((no_instrument_function))
10
11 /** A wrapper for Switch_lock that works even when the threading system
12     has not been intialized yet.
13     This wrapper is necessary because most lock-protected objects are 
14     initialized before the threading system has been fired up.
15  */
16 class Helping_lock : private Switch_lock
17 {
18
19 public:
20   using Switch_lock::Status;
21   using Switch_lock::Not_locked;
22   using Switch_lock::Locked;
23   using Switch_lock::Invalid;
24
25   using Switch_lock::invalidate;
26   using Switch_lock::valid;
27   using Switch_lock::wait_free;
28
29   static bool threading_system_active;
30 };
31
32 #undef NO_INSTRUMENT
33 #define NO_INSTRUMENT
34
35 IMPLEMENTATION:
36
37 #include "globals.h"
38 #include "panic.h"
39 #include "std_macros.h"
40
41
42 /** Threading system activated. */
43 bool Helping_lock::threading_system_active = false;
44
45 /** Constructor. */
46 PUBLIC inline
47 Helping_lock::Helping_lock ()
48 {
49   Switch_lock::initialize();
50 }
51
52 /** Acquire the lock with priority inheritance.
53     @return true if we owned the lock already.  false otherwise.
54  */
55 PUBLIC inline
56 Helping_lock::Status NO_INSTRUMENT
57 Helping_lock::test_and_set ()
58 {
59   if (! threading_system_active) // still initializing?
60     return Not_locked;
61   
62   return Switch_lock::test_and_set();
63 }
64
65 /** Acquire the lock with priority inheritance.
66     If the lock is occupied, enqueue in list of helpers and lend CPU 
67     to current lock owner until we are the lock owner.
68  */
69 PUBLIC inline NEEDS ["panic.h"]
70 Helping_lock::Status NO_INSTRUMENT
71 Helping_lock::lock ()
72 {
73   return test_and_set();
74 }
75
76 /** Is lock set?.
77     @return true if lock is set.
78  */
79 PUBLIC inline NEEDS["std_macros.h"]
80 Helping_lock::Status NO_INSTRUMENT
81 Helping_lock::test ()
82 {
83   if (EXPECT_FALSE( ! threading_system_active) ) // still initializing?
84     return Not_locked;
85
86   return Switch_lock::test();
87 }
88
89 /** Free the lock.
90     Return the CPU to helper or next lock owner, whoever has the higher 
91     priority, given that thread's priority is higher that our's.
92  */
93 PUBLIC inline NEEDS["std_macros.h"]
94 void NO_INSTRUMENT
95 Helping_lock::clear()
96 {
97   if (EXPECT_FALSE( ! threading_system_active) ) // still initializing?
98     return;
99
100   Switch_lock::clear();
101 }
102
103 PUBLIC inline NEEDS[Helping_lock::clear]
104 void
105 Helping_lock::set(Status s)
106 {
107   if (!s)
108     clear();
109 }
110
111 /** Lock owner. 
112     @return current owner of the lock.  0 if there is no owner.
113  */
114 PUBLIC inline NEEDS["std_macros.h", "globals.h"]
115 Context* NO_INSTRUMENT
116 Helping_lock::lock_owner () const
117 {
118   if (EXPECT_FALSE( ! threading_system_active) ) // still initializing?
119     return current();
120
121   return Switch_lock::lock_owner();
122 }