source: libcfa/src/concurrency/mutex.cfa @ 3381ed7

arm-ehjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 3381ed7 was 3381ed7, checked in by Thierry Delisle <tdelisle@…>, 22 months ago

Added park/unpark primitives thread and removed BlockInternal?.
Converted monitors to use park unpark.
Intrusive Queue now mark next field when thread is inside queue.
Added several asserts to kernel and monitor.
Added a few tests for park and unpark.

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