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

ADT ast-experimental enum pthread-emulation qualifiedEnum
Last change on this file since ff55092 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
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.