source: libcfa/src/concurrency/mutex.cfa@ e0c235c

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 e0c235c was 121be3e, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

change NULL to 0p

  • Property mode set to 100644
File size: 4.0 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.c --
10//
11// Author : Thierry Delisle
12// Created On : Fri May 25 01:37:11 2018
13// Last Modified By : Peter A. Buhr
14// Last Modified On : Wed Dec 4 09:16:39 2019
15// Update Count : 1
16//
17
18#define __cforall_thread__
19
20#include "mutex.hfa"
21
22#include "kernel_private.hfa"
23
24//-----------------------------------------------------------------------------
25// Locks
26
27// Exclusive lock - non-recursive
28// ---
29void ?{}(mutex_lock & this) {
30 this.lock{};
31 this.blocked_threads{};
32}
33
34void ^?{}(mutex_lock & this) {
35 // default
36}
37
38void lock(mutex_lock & this) with(this) {
39 lock( lock __cfaabi_dbg_ctx2 );
40 if( is_locked ) {
41 append( blocked_threads, kernelTLS.this_thread );
42 BlockInternal( &lock );
43 }
44 else {
45 is_locked = true;
46 unlock( lock );
47 }
48}
49
50bool try_lock(mutex_lock & this) with(this) {
51 bool ret = false;
52 lock( lock __cfaabi_dbg_ctx2 );
53 if( !is_locked ) {
54 ret = true;
55 is_locked = true;
56 }
57 unlock( lock );
58 return ret;
59}
60
61void unlock(mutex_lock & this) {
62 lock( this.lock __cfaabi_dbg_ctx2 );
63 this.is_locked = (this.blocked_threads != 0);
64 WakeThread(
65 pop_head( this.blocked_threads )
66 );
67 unlock( this.lock );
68}
69
70// Exclusive lock - non-recursive
71// ---
72void ?{}(recursive_mutex_lock & this) {
73 this.lock{};
74 this.blocked_threads{};
75 this.owner = 0p;
76 this.recursion_count = 0;
77}
78
79void ^?{}(recursive_mutex_lock & this) {
80 // default
81}
82
83void lock(recursive_mutex_lock & this) with(this) {
84 lock( lock __cfaabi_dbg_ctx2 );
85 if( owner == 0p ) {
86 owner = kernelTLS.this_thread;
87 recursion_count = 1;
88 unlock( lock );
89 }
90 else if( owner == kernelTLS.this_thread ) {
91 recursion_count++;
92 unlock( lock );
93 }
94 else {
95 append( blocked_threads, kernelTLS.this_thread );
96 BlockInternal( &lock );
97 }
98}
99
100bool try_lock(recursive_mutex_lock & this) with(this) {
101 bool ret = false;
102 lock( lock __cfaabi_dbg_ctx2 );
103 if( owner == 0p ) {
104 owner = kernelTLS.this_thread;
105 recursion_count = 1;
106 ret = true;
107 }
108 else if( owner == kernelTLS.this_thread ) {
109 recursion_count++;
110 ret = true;
111 }
112 unlock( lock );
113 return ret;
114}
115
116void unlock(recursive_mutex_lock & this) with(this) {
117 lock( lock __cfaabi_dbg_ctx2 );
118 recursion_count--;
119 if( recursion_count == 0 ) {
120 thread_desc * thrd = pop_head( blocked_threads );
121 owner = thrd;
122 recursion_count = (thrd ? 1 : 0);
123 WakeThread( thrd );
124 }
125 unlock( lock );
126}
127
128//-----------------------------------------------------------------------------
129// Conditions
130void ?{}(condition_variable & this) {
131 this.blocked_threads{};
132}
133
134void ^?{}(condition_variable & this) {
135 // default
136}
137
138void notify_one(condition_variable & this) with(this) {
139 lock( lock __cfaabi_dbg_ctx2 );
140 WakeThread(
141 pop_head( this.blocked_threads )
142 );
143 unlock( lock );
144}
145
146void notify_all(condition_variable & this) with(this) {
147 lock( lock __cfaabi_dbg_ctx2 );
148 while(this.blocked_threads) {
149 WakeThread(
150 pop_head( this.blocked_threads )
151 );
152 }
153 unlock( lock );
154}
155
156void wait(condition_variable & this) {
157 lock( this.lock __cfaabi_dbg_ctx2 );
158 append( this.blocked_threads, kernelTLS.this_thread );
159 BlockInternal( &this.lock );
160}
161
162forall(dtype L | is_lock(L))
163void wait(condition_variable & this, L & l) {
164 lock( this.lock __cfaabi_dbg_ctx2 );
165 append( this.blocked_threads, kernelTLS.this_thread );
166 void __unlock(void) {
167 unlock(l);
168 unlock(this.lock);
169 }
170 BlockInternal( __unlock );
171 lock(l);
172}
173
174//-----------------------------------------------------------------------------
175// Scopes
176forall(dtype L | is_lock(L))
177void lock_all ( L * locks[], size_t count) {
178 // Sort locks based on addresses
179 __libcfa_small_sort(locks, count);
180
181 // Lock all
182 for(size_t i = 0; i < count; i++) {
183 L * l = locks[i];
184 lock( *l );
185 }
186}
187
188forall(dtype L | is_lock(L))
189void unlock_all( L * locks[], size_t count) {
190 // Lock all
191 for(size_t i = 0; i < count; i++) {
192 L * l = locks[i];
193 unlock( *l );
194 }
195}
Note: See TracBrowser for help on using the repository browser.