source: libcfa/src/concurrency/mutex.cfa @ 748877f

Last change on this file since 748877f was ed52dd5, checked in by Peter A. Buhr <pabuhr@…>, 21 months ago

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