source: libcfa/src/concurrency/mutex.cfa @ 2026bb6

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 2026bb6 was 2026bb6, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

More robust fix for optionally linking threads

  • 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 : Thierry Delisle
14// Last Modified On : Fri May 25 01:37:51 2018
15// Update Count     : 0
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 = NULL;
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 == NULL ) {
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 == NULL ) {
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.