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

arm-ehenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since ae66348 was ae66348, checked in by Thierry Delisle <tdelisle@…>, 3 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.