source: libcfa/src/concurrency/locks.hfa@ 6a77224

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 6a77224 was 848439f, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Fixed newlines and tabs in concurrency/locks

  • Property mode set to 100644
File size: 6.6 KB
Line 
1#include <stdbool.h>
2
3#include "bits/algorithm.hfa"
4#include "bits/locks.hfa"
5#include "bits/containers.hfa"
6
7#include "invoke.h"
8
9#include "time_t.hfa"
10#include "time.hfa"
11#include <sys/time.h>
12
13///////////////////////////////////////////////////////////////////
14//// is_blocking_lock
15///////////////////////////////////////////////////////////////////
16
17trait is_blocking_lock(dtype L | sized(L)) {
18 void add_( L &, struct $thread * ); // For synchronization locks to use when acquiring
19 void remove_( L & ); // For synchronization locks to use when releasing
20 size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
21 void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
22};
23
24///////////////////////////////////////////////////////////////////
25//// info_thread
26///////////////////////////////////////////////////////////////////
27
28forall(dtype L | is_blocking_lock(L)) {
29 struct info_thread {
30 struct $thread * t;
31 uintptr_t info;
32 info_thread(L) * next;
33 L * lock;
34 };
35
36
37 void ?{}( info_thread(L) & this, $thread * t );
38 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
39 void ^?{}( info_thread(L) & this );
40
41 info_thread(L) *& get_next( info_thread(L) & this );
42}
43
44///////////////////////////////////////////////////////////////////
45//// Blocking Locks
46///////////////////////////////////////////////////////////////////
47struct blocking_lock {
48 // Spin lock used for mutual exclusion
49 __spinlock_t lock;
50
51 // List of blocked threads
52 __queue_t( struct $thread ) blocked_threads;
53
54 // Count of current blocked threads
55 size_t wait_count;
56
57 // Flag if the lock allows multiple acquisition
58 bool multi_acquisition;
59
60 // Flag if lock can be released by non owner
61 bool strict_owner;
62
63 // Current thread owning the lock
64 struct $thread * owner;
65
66 // Number of recursion level
67 size_t recursion_count;
68};
69
70struct mutex_lock {
71 inline blocking_lock;
72};
73
74struct owner_lock {
75 inline blocking_lock;
76};
77
78struct recursive_mutex_lock {
79 inline blocking_lock;
80};
81
82void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
83void ^?{}( blocking_lock & this );
84
85void ?{}( mutex_lock & this );
86void ^?{}( mutex_lock & this );
87
88void ?{}( owner_lock & this );
89void ^?{}( owner_lock & this );
90
91void ?{}( recursive_mutex_lock & this );
92void ^?{}( recursive_mutex_lock & this );
93
94void lock( blocking_lock & this );
95bool try_lock( blocking_lock & this );
96void unlock( blocking_lock & this );
97void add_( blocking_lock & this, struct $thread * t );
98void remove_( blocking_lock & this );
99size_t wait_count( blocking_lock & this );
100void set_recursion_count( blocking_lock & this, size_t recursion );
101size_t get_recursion_count( blocking_lock & this );
102
103void lock( mutex_lock & this );
104void unlock( mutex_lock & this );
105void add_( mutex_lock & this, struct $thread * t );
106void remove_( mutex_lock & this );
107void set_recursion_count( mutex_lock & this, size_t recursion );
108size_t get_recursion_count( mutex_lock & this );
109
110void lock( recursive_mutex_lock & this );
111void unlock( recursive_mutex_lock & this );
112void add_( recursive_mutex_lock & this, struct $thread * t );
113void remove_( recursive_mutex_lock & this );
114void set_recursion_count( recursive_mutex_lock & this, size_t recursion );
115size_t get_recursion_count( recursive_mutex_lock & this );
116
117///////////////////////////////////////////////////////////////////
118//// Synchronization Locks
119///////////////////////////////////////////////////////////////////
120forall(dtype L | is_blocking_lock(L)) {
121 struct synchronization_lock {
122 // Spin lock used for mutual exclusion
123 __spinlock_t lock;
124
125 // List of blocked threads
126 __queue_t( info_thread(L) ) blocked_threads;
127
128 // Count of current blocked threads
129 int count;
130
131 // If true threads will reacquire the lock they block on upon waking
132 bool reacquire_after_signal;
133 };
134
135 struct condition_variable {
136 inline synchronization_lock(L);
137 };
138
139 struct thread_queue {
140 inline synchronization_lock(L);
141 };
142
143
144 void ?{}( synchronization_lock(L) & this, bool multi_acquisition, bool strict_owner );
145 void ^?{}( synchronization_lock(L) & this );
146
147 void ?{}( condition_variable(L) & this );
148 void ^?{}( condition_variable(L) & this );
149
150 void ?{}( thread_queue(L) & this );
151 void ^?{}( thread_queue(L) & this );
152
153 bool notify_one( synchronization_lock(L) & this );
154 bool notify_all( synchronization_lock(L) & this );
155
156 uintptr_t front( synchronization_lock(L) & this );
157
158 bool empty( synchronization_lock(L) & this );
159 int counter( synchronization_lock(L) & this );
160
161 // wait functions that are not passed a mutex lock
162 void wait( synchronization_lock(L) & this );
163 void wait( synchronization_lock(L) & this, uintptr_t info );
164 bool wait( synchronization_lock(L) & this, Duration duration );
165 bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration );
166 bool wait( synchronization_lock(L) & this, Time time );
167 bool wait( synchronization_lock(L) & this, uintptr_t info, Time time );
168
169 // wait functions that are passed a lock
170 bool notify_one( synchronization_lock(L) & this, L & l );
171 bool notify_all( synchronization_lock(L) & this, L & l );
172
173 void wait( synchronization_lock(L) & this, L & l );
174 void wait( synchronization_lock(L) & this, L & l, uintptr_t info );
175 bool wait( synchronization_lock(L) & this, L & l, Duration duration );
176 bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration );
177 bool wait( synchronization_lock(L) & this, L & l, Time time );
178 bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time );
179}
180
181///////////////////////////////////////////////////////////////////
182//// condition lock alternative approach
183///////////////////////////////////////////////////////////////////
184
185
186///////////////////////////////////////////////////////////////////
187//// is_simple_lock
188///////////////////////////////////////////////////////////////////
189
190trait is_simple_lock(dtype L | sized(L)) {
191 void lock( L & ); // For synchronization locks to use when acquiring
192 void unlock( L & ); // For synchronization locks to use when releasing
193 size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
194 void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
195};
196
197forall(dtype L | is_simple_lock(L)) {
198 struct condition_lock {
199 // Spin lock used for mutual exclusion
200 mutex_lock m_lock;
201
202 condition_variable( mutex_lock ) c_var;
203 };
204
205 void ?{}( condition_lock(L) & this );
206 void ^?{}( condition_lock(L) & this );
207
208 bool notify_one( condition_lock(L) & this );
209 bool notify_all( condition_lock(L) & this );
210 void wait( condition_lock(L) & this, L & l );
211}
Note: See TracBrowser for help on using the repository browser.