source: libcfa/src/concurrency/locks.hfa @ ae2c27a

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since ae2c27a was ae2c27a, checked in by Colby Alexander Parsons <caparsons@…>, 3 years ago

Added unified condition variable prototypes

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[ae2c27a]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.