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

ADT ast-experimental enum pthread-emulation qualifiedEnum
Last change on this file since f870e257 was 708ae38, checked in by Thierry Delisle <tdelisle@…>, 4 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.