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

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since cad1df1 was cad1df1, checked in by Colby Alexander Parsons <caparsons@…>, 11 months ago

fixed a lot of bugs and integrated new sequence changes

  • 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#include "bits/containers.hfa"
9
10#include "invoke.h"
11
12#include "time_t.hfa"
13#include "time.hfa"
14#include <sys/time.h>
15#include "alarm.hfa"
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 {
34                inline Seqable;
35                struct $thread * t;
36                uintptr_t info;
37                L * lock;
38                bool listed;                                    // true if info_thread is on queue, false otherwise;
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 );
45}
46
47///////////////////////////////////////////////////////////////////
48//// Blocking Locks
49///////////////////////////////////////////////////////////////////
50
51// struct lock_thread {
52//      struct $thread * t;
53//      lock_thread * next;
54// };
55
56// void ?{}( lock_thread & this, struct $thread * thd );
57// void ^?{}( lock_thread & this );
58
59// lock_thread *& get_next( lock_thread & );
60
61struct blocking_lock {
62        // Spin lock used for mutual exclusion
63        __spinlock_t lock;
64
65        // List of blocked threads
66        __queue_t( $thread ) blocked_threads;
67
68        // Count of current blocked threads
69        size_t wait_count;
70
71        // Flag if the lock allows multiple acquisition
72        bool multi_acquisition;
73
74        // Flag if lock can be released by non owner
75        bool strict_owner;
76
77        // Current thread owning the lock
78        struct $thread * owner;
79
80        // Number of recursion level
81        size_t recursion_count;
82};
83
84struct single_acquisition_lock {
85        inline blocking_lock;
86};
87
88struct owner_lock {
89        inline blocking_lock;
90};
91
92struct multiple_acquisition_lock {
93        inline blocking_lock;
94};
95
96void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
97void ^?{}( blocking_lock & this );
98
99void ?{}( single_acquisition_lock & this );
100void ^?{}( single_acquisition_lock & this );
101
102void ?{}( owner_lock & this );
103void ^?{}( owner_lock & this );
104
105void ?{}( multiple_acquisition_lock & this );
106void ^?{}( multiple_acquisition_lock & this );
107
108void lock( blocking_lock & this );
109bool try_lock( blocking_lock & this );
110void unlock( blocking_lock & this );
111void add_( blocking_lock & this, struct $thread * t );
112void remove_( blocking_lock & this );
113size_t wait_count( blocking_lock & this );
114void set_recursion_count( blocking_lock & this, size_t recursion );
115size_t get_recursion_count( blocking_lock & this );
116
117void lock( single_acquisition_lock & this );
118void unlock( single_acquisition_lock & this );
119void add_( single_acquisition_lock & this, struct $thread * t );
120void remove_( single_acquisition_lock & this );
121void set_recursion_count( single_acquisition_lock & this, size_t recursion );
122size_t get_recursion_count( single_acquisition_lock & this );
123
124void lock( owner_lock & this );
125void unlock( owner_lock & this );
126void add_( owner_lock & this, struct $thread * t );
127void remove_( owner_lock & this );
128void set_recursion_count( owner_lock & this, size_t recursion );
129size_t get_recursion_count( owner_lock & this );
130
131void lock( multiple_acquisition_lock & this );
132void unlock( multiple_acquisition_lock & this );
133void add_( multiple_acquisition_lock & this, struct $thread * t );
134void remove_( multiple_acquisition_lock & this );
135void set_recursion_count( multiple_acquisition_lock & this, size_t recursion );
136size_t get_recursion_count( multiple_acquisition_lock & this );
137
138///////////////////////////////////////////////////////////////////
139//// Synchronization Locks
140///////////////////////////////////////////////////////////////////
141forall(dtype L | is_blocking_lock(L)) {
142        struct condition_variable {
143                // Spin lock used for mutual exclusion
144                __spinlock_t lock;
145
146                info_thread(L) * last_thread;
147
148                // List of blocked threads
149                Sequence( info_thread(L) ) blocked_threads;
150
151                // Count of current blocked threads
152                int count;
153        };
154
155        void ?{}( condition_variable(L) & this );
156        void ^?{}( condition_variable(L) & this );
157
158        struct alarm_node_wrap {
159                alarm_node_t alarm_node;
160
161                condition_variable(L) * cond;
162
163                info_thread(L) * i;
164        };
165
166        void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
167        void ^?{}( alarm_node_wrap(L) & this );
168
169        void alarm_node_callback( alarm_node_wrap(L) & this );
170
171        void alarm_node_wrap_cast( alarm_node_t & a );
172
173        bool notify_one( condition_variable(L) & this );
174        bool notify_all( condition_variable(L) & this );
175
176        uintptr_t front( condition_variable(L) & this );
177
178        bool empty( condition_variable(L) & this );
179        int counter( condition_variable(L) & this );
180
181        // TODO: look into changing timout routines to return bool showing if signalled or woken by kernel
182        void wait( condition_variable(L) & this );
183        void wait( condition_variable(L) & this, uintptr_t info );
184        void wait( condition_variable(L) & this, Duration duration );
185        void wait( condition_variable(L) & this, uintptr_t info, Duration duration );
186        void wait( condition_variable(L) & this, Time time );
187        void wait( condition_variable(L) & this, uintptr_t info, Time time );
188
189        void wait( condition_variable(L) & this, L & l );
190        void wait( condition_variable(L) & this, L & l, uintptr_t info );
191        void wait( condition_variable(L) & this, L & l, Duration duration );
192        void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
193        void wait( condition_variable(L) & this, L & l, Time time );
194        void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
195}
Note: See TracBrowser for help on using the repository browser.