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

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 a8078eef was 3381ed7, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Added park/unpark primitives thread and removed BlockInternal.
Converted monitors to use park unpark.
Intrusive Queue now mark next field when thread is inside queue.
Added several asserts to kernel and monitor.
Added a few tests for park and unpark.

  • Property mode set to 100644
File size: 3.9 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 unlock( lock );
43 park();
44 }
45 else {
46 is_locked = true;
47 unlock( lock );
48 }
49}
50
51bool try_lock(mutex_lock & this) with(this) {
52 bool ret = false;
53 lock( lock __cfaabi_dbg_ctx2 );
54 if( !is_locked ) {
55 ret = true;
56 is_locked = true;
57 }
58 unlock( lock );
59 return ret;
60}
61
62void unlock(mutex_lock & this) {
63 lock( this.lock __cfaabi_dbg_ctx2 );
64 this.is_locked = (this.blocked_threads != 0);
65 unpark(
66 pop_head( this.blocked_threads )
67 );
68 unlock( this.lock );
69}
70
71// Exclusive lock - non-recursive
72// ---
73void ?{}(recursive_mutex_lock & this) {
74 this.lock{};
75 this.blocked_threads{};
76 this.owner = 0p;
77 this.recursion_count = 0;
78}
79
80void ^?{}(recursive_mutex_lock & this) {
81 // default
82}
83
84void lock(recursive_mutex_lock & this) with(this) {
85 lock( lock __cfaabi_dbg_ctx2 );
86 if( owner == 0p ) {
87 owner = kernelTLS.this_thread;
88 recursion_count = 1;
89 unlock( lock );
90 }
91 else if( owner == kernelTLS.this_thread ) {
92 recursion_count++;
93 unlock( lock );
94 }
95 else {
96 append( blocked_threads, kernelTLS.this_thread );
97 unlock( lock );
98 park();
99 }
100}
101
102bool try_lock(recursive_mutex_lock & this) with(this) {
103 bool ret = false;
104 lock( lock __cfaabi_dbg_ctx2 );
105 if( owner == 0p ) {
106 owner = kernelTLS.this_thread;
107 recursion_count = 1;
108 ret = true;
109 }
110 else if( owner == kernelTLS.this_thread ) {
111 recursion_count++;
112 ret = true;
113 }
114 unlock( lock );
115 return ret;
116}
117
118void unlock(recursive_mutex_lock & this) with(this) {
119 lock( lock __cfaabi_dbg_ctx2 );
120 recursion_count--;
121 if( recursion_count == 0 ) {
122 thread_desc * thrd = pop_head( blocked_threads );
123 owner = thrd;
124 recursion_count = (thrd ? 1 : 0);
125 unpark( thrd );
126 }
127 unlock( lock );
128}
129
130//-----------------------------------------------------------------------------
131// Conditions
132void ?{}(condition_variable & this) {
133 this.blocked_threads{};
134}
135
136void ^?{}(condition_variable & this) {
137 // default
138}
139
140void notify_one(condition_variable & this) with(this) {
141 lock( lock __cfaabi_dbg_ctx2 );
142 unpark(
143 pop_head( this.blocked_threads )
144 );
145 unlock( lock );
146}
147
148void notify_all(condition_variable & this) with(this) {
149 lock( lock __cfaabi_dbg_ctx2 );
150 while(this.blocked_threads) {
151 unpark(
152 pop_head( this.blocked_threads )
153 );
154 }
155 unlock( lock );
156}
157
158void wait(condition_variable & this) {
159 lock( this.lock __cfaabi_dbg_ctx2 );
160 append( this.blocked_threads, kernelTLS.this_thread );
161 unlock( this.lock );
162 park();
163}
164
165forall(dtype L | is_lock(L))
166void wait(condition_variable & this, L & l) {
167 lock( this.lock __cfaabi_dbg_ctx2 );
168 append( this.blocked_threads, kernelTLS.this_thread );
169 unlock(l);
170 unlock(this.lock);
171 park();
172 lock(l);
173}
174
175//-----------------------------------------------------------------------------
176// Scopes
177forall(dtype L | is_lock(L))
178void lock_all ( L * locks[], size_t count) {
179 // Sort locks based on addresses
180 __libcfa_small_sort(locks, count);
181
182 // Lock all
183 for(size_t i = 0; i < count; i++) {
184 L * l = locks[i];
185 lock( *l );
186 }
187}
188
189forall(dtype L | is_lock(L))
190void unlock_all( L * locks[], size_t count) {
191 // Lock all
192 for(size_t i = 0; i < count; i++) {
193 L * l = locks[i];
194 unlock( *l );
195 }
196}
Note: See TracBrowser for help on using the repository browser.