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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since c20533ea was c20533ea, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Fixed locks.hfa to no longer depend on private headers bits/algorithm.hfa and alarm.hfa

  • Property mode set to 100644
File size: 5.6 KB
Line 
1#pragma once
2
3#include <stdbool.h>
4
5#include "bits/locks.hfa"
6#include "bits/sequence.hfa"
7
8#include "invoke.h"
9
10#include "time_t.hfa"
11#include "time.hfa"
12#include <sys/time.h>
13
14///////////////////////////////////////////////////////////////////
15//// is_blocking_lock
16///////////////////////////////////////////////////////////////////
17
18trait is_blocking_lock(dtype L | sized(L)) {
19        void on_notify( L &, struct $thread * );                        // For synchronization locks to use when acquiring
20        void on_wait( 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
29// the info thread is a wrapper around a thread used
30// to store extra data for use in the condition variable
31forall(dtype L | is_blocking_lock(L)) {
32        struct info_thread {
33                inline Seqable;                                 // used to put info_thread on a dl queue (aka sequence)
34                struct $thread * t;                             // waiting thread
35                uintptr_t info;                                 // shadow field
36                L * lock;                                               // lock that is passed to wait() (if one is passed)
37                bool signalled;                                 // true when signalled and false when timeout wakes thread
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        // for use by sequence
46        info_thread(L) *& Back( info_thread(L) * this );
47        info_thread(L) *& Next( info_thread(L) * this );
48}
49
50///////////////////////////////////////////////////////////////////
51//// Blocking Locks
52///////////////////////////////////////////////////////////////////
53
54struct blocking_lock {
55        // Spin lock used for mutual exclusion
56        __spinlock_t lock;
57
58        // List of blocked threads
59        Sequence( $thread ) blocked_threads;
60
61        // Count of current blocked threads
62        size_t wait_count;
63
64        // Flag if the lock allows multiple acquisition
65        bool multi_acquisition;
66
67        // Flag if lock can be released by non owner
68        bool strict_owner;
69
70        // Current thread owning the lock
71        struct $thread * owner;
72
73        // Number of recursion level
74        size_t recursion_count;
75};
76
77struct single_acquisition_lock {
78        inline blocking_lock;
79};
80
81struct owner_lock {
82        inline blocking_lock;
83};
84
85struct multiple_acquisition_lock {
86        inline blocking_lock;
87};
88
89void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
90void ^?{}( blocking_lock & this );
91
92void ?{}( single_acquisition_lock & this );
93void ^?{}( single_acquisition_lock & this );
94
95void ?{}( owner_lock & this );
96void ^?{}( owner_lock & this );
97
98void ?{}( multiple_acquisition_lock & this );
99void ^?{}( multiple_acquisition_lock & this );
100
101void lock( blocking_lock & this );
102bool try_lock( blocking_lock & this );
103void unlock( blocking_lock & this );
104void on_notify( blocking_lock & this, struct $thread * t );
105void on_wait( blocking_lock & this );
106size_t wait_count( blocking_lock & this );
107void set_recursion_count( blocking_lock & this, size_t recursion );
108size_t get_recursion_count( blocking_lock & this );
109
110void lock( single_acquisition_lock & this );
111void unlock( single_acquisition_lock & this );
112void on_notify( single_acquisition_lock & this, struct $thread * t );
113void on_wait( single_acquisition_lock & this );
114void set_recursion_count( single_acquisition_lock & this, size_t recursion );
115size_t get_recursion_count( single_acquisition_lock & this );
116
117void lock( owner_lock & this );
118void unlock( owner_lock & this );
119void on_notify( owner_lock & this, struct $thread * t );
120void on_wait( owner_lock & this );
121void set_recursion_count( owner_lock & this, size_t recursion );
122size_t get_recursion_count( owner_lock & this );
123
124void lock( multiple_acquisition_lock & this );
125void unlock( multiple_acquisition_lock & this );
126void on_notify( multiple_acquisition_lock & this, struct $thread * t );
127void on_wait( multiple_acquisition_lock & this );
128void set_recursion_count( multiple_acquisition_lock & this, size_t recursion );
129size_t get_recursion_count( multiple_acquisition_lock & this );
130
131///////////////////////////////////////////////////////////////////
132//// Synchronization Locks
133///////////////////////////////////////////////////////////////////
134forall(dtype L | is_blocking_lock(L)) {
135        struct condition_variable {
136                // Spin lock used for mutual exclusion
137                __spinlock_t lock;
138
139                // List of blocked threads
140                Sequence( info_thread(L) ) blocked_threads;
141
142                // Count of current blocked threads
143                int count;
144        };
145
146        void ?{}( condition_variable(L) & this );
147        void ^?{}( condition_variable(L) & this );
148
149        bool notify_one( condition_variable(L) & this );
150        bool notify_all( condition_variable(L) & this );
151
152        uintptr_t front( condition_variable(L) & this );
153
154        bool empty( condition_variable(L) & this );
155        int counter( condition_variable(L) & this );
156
157        void wait( condition_variable(L) & this );
158        void wait( condition_variable(L) & this, uintptr_t info );
159        bool wait( condition_variable(L) & this, Duration duration );
160        bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
161        bool wait( condition_variable(L) & this, Time time );
162        bool wait( condition_variable(L) & this, uintptr_t info, Time time );
163
164        void wait( condition_variable(L) & this, L & l );
165        void wait( condition_variable(L) & this, L & l, uintptr_t info );
166        bool wait( condition_variable(L) & this, L & l, Duration duration );
167        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
168        bool wait( condition_variable(L) & this, L & l, Time time );
169        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
170}
Note: See TracBrowser for help on using the repository browser.