source: libcfa/src/concurrency/locks.hfa@ 751e2eb

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 751e2eb was c131a02, checked in by Colby Alexander Parsons <caparsons@…>, 5 years ago

added support for threads in sequence

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