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

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since ae06e0b was 708ae38, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Some more cleanup and grow/shrink now readjusts io timestamps.
(They are still unused).

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