source: libcfa/src/concurrency/mutex.hfa@ 5b2b42e

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 5b2b42e was 121be3e, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

change NULL to 0p

  • Property mode set to 100644
File size: 3.7 KB
Line 
1
2// -*- Mode: CFA -*-
3//
4// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
5//
6// The contents of this file are covered under the licence agreement in the
7// file "LICENCE" distributed with Cforall.
8//
9// mutex --
10//
11// Author : Thierry Delisle
12// Created On : Fri May 25 01:24:09 2018
13// Last Modified By : Peter A. Buhr
14// Last Modified On : Wed Dec 4 09:16:53 2019
15// Update Count : 1
16//
17
18#pragma once
19
20#include <stdbool.h>
21
22#include "bits/algorithm.hfa"
23#include "bits/locks.hfa"
24
25#include "invoke.h"
26#include "time_t.hfa"
27
28//-----------------------------------------------------------------------------
29// Locks
30
31// Exclusive lock - non-recursive
32// ---
33struct mutex_lock {
34 // Spin lock used for mutual exclusion
35 __spinlock_t lock;
36
37 // List of blocked threads
38 __queue_t(struct thread_desc) blocked_threads;
39
40 // Locked flag
41 bool is_locked;
42};
43
44void ?{}(mutex_lock & this);
45void ^?{}(mutex_lock & this);
46void lock(mutex_lock & this);
47bool try_lock(mutex_lock & this);
48void unlock(mutex_lock & this);
49
50// Exclusive lock - recursive
51// ---
52struct recursive_mutex_lock{
53 // Spin lock used for mutual exclusion
54 __spinlock_t lock;
55
56 // List of blocked threads
57 __queue_t(struct thread_desc) blocked_threads;
58
59 // Current thread owning the lock
60 struct thread_desc * owner;
61
62 // Number of recursion level
63 size_t recursion_count;
64};
65
66void ?{}(recursive_mutex_lock & this);
67void ^?{}(recursive_mutex_lock & this);
68void lock(recursive_mutex_lock & this);
69bool try_lock(recursive_mutex_lock & this);
70void unlock(recursive_mutex_lock & this);
71
72trait is_lock(dtype L | sized(L)) {
73 void lock (L &);
74 void unlock(L &);
75};
76
77//-----------------------------------------------------------------------------
78// Condition variables
79
80struct condition_variable {
81 // Spin lock used for mutual exclusion
82 __spinlock_t lock;
83
84 // List of blocked threads
85 __queue_t(struct thread_desc) blocked_threads;
86};
87
88void ?{}(condition_variable & this);
89void ^?{}(condition_variable & this);
90
91void notify_one(condition_variable & this);
92void notify_all(condition_variable & this);
93
94void wait(condition_variable & this);
95
96forall(dtype L | is_lock(L))
97void wait(condition_variable & this, L & l);
98
99//-----------------------------------------------------------------------------
100// Scopes
101forall(dtype L | is_lock(L)) {
102 #if !defined( __TUPLE_ARRAYS_EXIST__ )
103 void lock ( L * locks [], size_t count);
104 void unlock( L * locks [], size_t count);
105
106 struct lock_scope {
107 L ** locks;
108 size_t count;
109 };
110
111 static inline void ?{}(lock_scope(L) & this) {
112 this.locks = 0p;
113 this.count = 0;
114 }
115
116 static inline void ^?{}(lock_scope(L) & this) {
117 if(this.count > 0) {
118 unlock(this.locks, this.count);
119 }
120 }
121
122 static inline lock_scope(L) lock( L * locks [], size_t count, lock_scope(L) & scope) {
123 lock(locks, count);
124 scope.locks = locks;
125 scope.count = count;
126 }
127
128 static inline void unlock( lock_scope(L) & this ) {
129 unlock(this.locks, this.count);
130 this.count = 0;
131 }
132
133 static inline void release( lock_scope(L) & this ) {
134 this.count = 0;
135 }
136 #else
137 void lock( [L &...] locks );
138 void unlock( [L &...] locks );
139
140 forall(size_t N)
141 struct lock_scope {
142 bool released;
143 [L &... N] locks;
144 };
145
146 void ?{}(lock_scope(L) & this) = void;
147 void ?{}(lock_scope(L) & this, lock_scope(L) other) = void;
148 void ?move?(lock_scope(L) & this, lock_scope(L) & other) = default;
149
150 static inline void ^?{}(lock_scope(L) & this) {
151 if( !this.released ) {
152 unlock(this.locks);
153 }
154 }
155
156 forall(size_t N)
157 static inline lock_scope(L, N) lock( [L &...] locks ) {
158 lock(locks);
159 return @{false, locks};
160 }
161
162 static inline void unlock( lock_scope(L) & this ) {
163 unlock(this.locks);
164 this.released = true
165 }
166
167 static inline void release( lock_scope(L) & this ) {
168 this.released = true;
169 }
170 #endif
171}
Note: See TracBrowser for help on using the repository browser.