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

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

added full timeout functionality to unified condition variables

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