source: libcfa/src/concurrency/mutex.cfa @ 2b910f9

ADTast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 2b910f9 was 43784ac, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Changed libcfathread to consistently define _GNU_SOURCE

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