source: libcfa/src/concurrency/locks.hfa@ 62a7cc0

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 62a7cc0 was 797a193, checked in by caparsons <caparson@…>, 5 years ago

cleaned up locks code and added comments

  • Property mode set to 100644
File size: 6.0 KB
Line 
1#pragma once
2
3#include <stdbool.h>
4
5#include "bits/algorithm.hfa"
6#include "bits/locks.hfa"
7#include "bits/sequence.hfa"
8
9#include "invoke.h"
10
11#include "time_t.hfa"
12#include "time.hfa"
13#include <sys/time.h>
14#include "alarm.hfa"
15
16///////////////////////////////////////////////////////////////////
17//// is_blocking_lock
18///////////////////////////////////////////////////////////////////
19
20trait is_blocking_lock(dtype L | sized(L)) {
21 void on_notify( L &, struct $thread * ); // For synchronization locks to use when acquiring
22 void on_wait( L & ); // For synchronization locks to use when releasing
23 size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
24 void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
25};
26
27///////////////////////////////////////////////////////////////////
28//// info_thread
29///////////////////////////////////////////////////////////////////
30
31// the info thread is a wrapper around a thread used
32// to store extra data for use in the condition variable
33forall(dtype L | is_blocking_lock(L)) {
34 struct info_thread {
35 inline Seqable; // used to put info_thread on a dl queue (aka sequence)
36 struct $thread * t; // waiting thread
37 uintptr_t info; // shadow field
38 L * lock; // lock that is passed to wait() (if one is passed)
39 bool signalled; // true when signalled and false when timeout wakes thread
40 };
41
42
43 void ?{}( info_thread(L) & this, $thread * t );
44 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
45 void ^?{}( info_thread(L) & this );
46
47 // for use by sequence
48 info_thread(L) *& Back( info_thread(L) * this );
49 info_thread(L) *& Next( info_thread(L) * this );
50}
51
52///////////////////////////////////////////////////////////////////
53//// Blocking Locks
54///////////////////////////////////////////////////////////////////
55
56struct blocking_lock {
57 // Spin lock used for mutual exclusion
58 __spinlock_t lock;
59
60 // List of blocked threads
61 Sequence( $thread ) blocked_threads;
62
63 // Count of current blocked threads
64 size_t wait_count;
65
66 // Flag if the lock allows multiple acquisition
67 bool multi_acquisition;
68
69 // Flag if lock can be released by non owner
70 bool strict_owner;
71
72 // Current thread owning the lock
73 struct $thread * owner;
74
75 // Number of recursion level
76 size_t recursion_count;
77};
78
79struct single_acquisition_lock {
80 inline blocking_lock;
81};
82
83struct owner_lock {
84 inline blocking_lock;
85};
86
87struct multiple_acquisition_lock {
88 inline blocking_lock;
89};
90
91void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
92void ^?{}( blocking_lock & this );
93
94void ?{}( single_acquisition_lock & this );
95void ^?{}( single_acquisition_lock & this );
96
97void ?{}( owner_lock & this );
98void ^?{}( owner_lock & this );
99
100void ?{}( multiple_acquisition_lock & this );
101void ^?{}( multiple_acquisition_lock & this );
102
103void lock( blocking_lock & this );
104bool try_lock( blocking_lock & this );
105void unlock( blocking_lock & this );
106void on_notify( blocking_lock & this, struct $thread * t );
107void on_wait( blocking_lock & this );
108size_t wait_count( blocking_lock & this );
109void set_recursion_count( blocking_lock & this, size_t recursion );
110size_t get_recursion_count( blocking_lock & this );
111
112void lock( single_acquisition_lock & this );
113void unlock( single_acquisition_lock & this );
114void on_notify( single_acquisition_lock & this, struct $thread * t );
115void on_wait( single_acquisition_lock & this );
116void set_recursion_count( single_acquisition_lock & this, size_t recursion );
117size_t get_recursion_count( single_acquisition_lock & this );
118
119void lock( owner_lock & this );
120void unlock( owner_lock & this );
121void on_notify( owner_lock & this, struct $thread * t );
122void on_wait( owner_lock & this );
123void set_recursion_count( owner_lock & this, size_t recursion );
124size_t get_recursion_count( owner_lock & this );
125
126void lock( multiple_acquisition_lock & this );
127void unlock( multiple_acquisition_lock & this );
128void on_notify( multiple_acquisition_lock & this, struct $thread * t );
129void on_wait( multiple_acquisition_lock & this );
130void set_recursion_count( multiple_acquisition_lock & this, size_t recursion );
131size_t get_recursion_count( multiple_acquisition_lock & this );
132
133///////////////////////////////////////////////////////////////////
134//// Synchronization Locks
135///////////////////////////////////////////////////////////////////
136forall(dtype L | is_blocking_lock(L)) {
137 struct condition_variable {
138 // Spin lock used for mutual exclusion
139 __spinlock_t lock;
140
141 // List of blocked threads
142 Sequence( info_thread(L) ) blocked_threads;
143
144 // Count of current blocked threads
145 int count;
146 };
147
148 void ?{}( condition_variable(L) & this );
149 void ^?{}( condition_variable(L) & this );
150
151 struct alarm_node_wrap {
152 alarm_node_t alarm_node;
153
154 condition_variable(L) * cond;
155
156 info_thread(L) * i;
157 };
158
159 void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );
160 void ^?{}( alarm_node_wrap(L) & this );
161
162 void alarm_node_callback( alarm_node_wrap(L) & this );
163
164 void alarm_node_wrap_cast( alarm_node_t & a );
165
166 bool notify_one( condition_variable(L) & this );
167 bool notify_all( condition_variable(L) & this );
168
169 uintptr_t front( condition_variable(L) & this );
170
171 bool empty( condition_variable(L) & this );
172 int counter( condition_variable(L) & this );
173
174 void wait( condition_variable(L) & this );
175 void wait( condition_variable(L) & this, uintptr_t info );
176 bool wait( condition_variable(L) & this, Duration duration );
177 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
178 bool wait( condition_variable(L) & this, Time time );
179 bool wait( condition_variable(L) & this, uintptr_t info, Time time );
180
181 void wait( condition_variable(L) & this, L & l );
182 void wait( condition_variable(L) & this, L & l, uintptr_t info );
183 bool wait( condition_variable(L) & this, L & l, Duration duration );
184 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
185 bool wait( condition_variable(L) & this, L & l, Time time );
186 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
187}
Note: See TracBrowser for help on using the repository browser.