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

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

fixed some bugs

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