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

Last change on this file since cf34e82 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
RevLine 
[09800e9]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
[121be3e]13// Last Modified By : Peter A. Buhr
[ed52dd5]14// Last Modified On : Sun Feb 19 17:01:36 2023
15// Update Count     : 3
[09800e9]16//
17
[2026bb6]18#define __cforall_thread__
19
[58b6d1b]20#include "mutex.hfa"
[09800e9]21
[708ae38]22#include "kernel/private.hfa"
[09800e9]23
24//-----------------------------------------------------------------------------
25// Locks
26
27// Exclusive lock - non-recursive
28// ---
29void ?{}(mutex_lock & this) {
30        this.lock{};
31        this.blocked_threads{};
[519f11c]32        this.is_locked = false;
[09800e9]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 ) {
[be73f30]42                append( blocked_threads, active_thread() );
[3381ed7]43                unlock( lock );
[e235429]44                park();
[09800e9]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 );
[6c7099a]65        this.is_locked = (this.blocked_threads != 0);
[3381ed7]66        unpark(
[e235429]67                pop_head( this.blocked_threads )
[09800e9]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{};
[121be3e]77        this.owner = 0p;
[09800e9]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 );
[121be3e]87        if( owner == 0p ) {
[be73f30]88                owner = active_thread();
[09800e9]89                recursion_count = 1;
90                unlock( lock );
91        }
[be73f30]92        else if( owner == active_thread() ) {
[09800e9]93                recursion_count++;
94                unlock( lock );
95        }
96        else {
[be73f30]97                append( blocked_threads, active_thread() );
[3381ed7]98                unlock( lock );
[e235429]99                park();
[09800e9]100        }
101}
102
103bool try_lock(recursive_mutex_lock & this) with(this) {
104        bool ret = false;
105        lock( lock __cfaabi_dbg_ctx2 );
[121be3e]106        if( owner == 0p ) {
[be73f30]107                owner = active_thread();
[09800e9]108                recursion_count = 1;
109                ret = true;
110        }
[be73f30]111        else if( owner == active_thread() ) {
[09800e9]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 ) {
[e84ab3d]123                thread$ * thrd = pop_head( blocked_threads );
[09800e9]124                owner = thrd;
125                recursion_count = (thrd ? 1 : 0);
[e235429]126                unpark( thrd );
[09800e9]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 );
[3381ed7]143        unpark(
[e235429]144                pop_head( this.blocked_threads )
[09800e9]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) {
[3381ed7]152                unpark(
[e235429]153                        pop_head( this.blocked_threads )
[09800e9]154                );
155        }
156        unlock( lock );
157}
158
159void wait(condition_variable & this) {
160        lock( this.lock __cfaabi_dbg_ctx2 );
[be73f30]161        append( this.blocked_threads, active_thread() );
[3381ed7]162        unlock( this.lock );
[e235429]163        park();
[09800e9]164}
165
[fd54fef]166forall(L & | is_lock(L))
[09800e9]167void wait(condition_variable & this, L & l) {
168        lock( this.lock __cfaabi_dbg_ctx2 );
[be73f30]169        append( this.blocked_threads, active_thread() );
[3381ed7]170        unlock(l);
171        unlock(this.lock);
[e235429]172        park();
[8cc7dd1]173        lock(l);
[09800e9]174}
175
176//-----------------------------------------------------------------------------
177// Scopes
[fd54fef]178forall(L & | is_lock(L))
[09800e9]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
[fd54fef]190forall(L & | is_lock(L))
[09800e9]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        }
[121be3e]197}
Note: See TracBrowser for help on using the repository browser.