source: libcfa/src/concurrency/mutex.cfa@ 1539bbd

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 1539bbd was ae66348, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Threads in debug now keep track of last function to park/unpark it

  • Property mode set to 100644
File size: 4.1 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( __cfaabi_dbg_ctx );
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 ) __cfaabi_dbg_ctx2
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( __cfaabi_dbg_ctx );
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 * thrd = pop_head( blocked_threads );
123 owner = thrd;
124 recursion_count = (thrd ? 1 : 0);
125 unpark( thrd __cfaabi_dbg_ctx2 );
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 ) __cfaabi_dbg_ctx2
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 ) __cfaabi_dbg_ctx2
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( __cfaabi_dbg_ctx );
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( __cfaabi_dbg_ctx );
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.