source: src/libcfa/concurrency/mutex @ 5510027

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since 5510027 was 09800e9, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

First draft at locks in Cforall

  • Property mode set to 100644
File size: 3.7 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 --
10//
11// Author           : Thierry Delisle
12// Created On       : Fri May 25 01:24:09 2018
13// Last Modified By : Thierry Delisle
14// Last Modified On : Fri May 25 01:24:12 2018
15// Update Count     : 0
16//
17
18#pragma once
19
20#include <stdbool.h>
21
22#include "bits/algorithms.h"
23#include "bits/locks.h"
24
25#include "invoke.h"
26#include "time_t.h"
27
28//-----------------------------------------------------------------------------
29// Locks
30
31// Exclusive lock - non-recursive
32// ---
33struct mutex_lock {
34        // Spin lock used for mutual exclusion
35        __spinlock_t lock;
36
37        // List of blocked threads
38        __queue_t(struct thread_desc) blocked_threads;
39
40        // Locked flag
41        bool is_locked;
42};
43
44void ?{}(mutex_lock & this);
45void ^?{}(mutex_lock & this);
46void lock(mutex_lock & this);
47bool try_lock(mutex_lock & this);
48void unlock(mutex_lock & this);
49
50// Exclusive lock - recursive
51// ---
52struct recursive_mutex_lock{
53        // Spin lock used for mutual exclusion
54        __spinlock_t lock;
55
56        // List of blocked threads
57        __queue_t(struct thread_desc) blocked_threads;
58
59        // Current thread owning the lock
60        struct thread_desc * owner;
61
62        // Number of recursion level
63        size_t recursion_count;
64};
65
66void ?{}(recursive_mutex_lock & this);
67void ^?{}(recursive_mutex_lock & this);
68void lock(recursive_mutex_lock & this);
69bool try_lock(recursive_mutex_lock & this);
70void unlock(recursive_mutex_lock & this);
71
72trait is_lock(dtype L | sized(L)) {
73        void lock  (L &);
74        void unlock(L &);
75};
76
77//-----------------------------------------------------------------------------
78// Condition variables
79
80struct condition_variable {
81        // Spin lock used for mutual exclusion
82        __spinlock_t lock;
83
84        // List of blocked threads
85        __queue_t(struct thread_desc) blocked_threads;
86};
87
88void ?{}(condition_variable & this);
89void ^?{}(condition_variable & this);
90
91void notify_one(condition_variable & this);
92void notify_all(condition_variable & this);
93
94void wait(condition_variable & this);
95
96forall(dtype L | is_lock(L))
97void wait(condition_variable & this, L & l);
98
99//-----------------------------------------------------------------------------
100// Scopes
101forall(dtype L | is_lock(L)) {
102        #if !defined( __TUPLE_ARRAYS_EXIST__ )
103        void lock  ( L * locks [], size_t count);
104        void unlock( L * locks [], size_t count);
105
106        struct lock_scope {
107                L **   locks;
108                size_t count;
109        };
110
111        static inline void ?{}(lock_scope(L) & this) {
112                this.locks = NULL;
113                this.count = 0;
114        }
115
116        static inline void ^?{}(lock_scope(L) & this) {
117                if(this.count > 0) {
118                        unlock(this.locks, this.count);
119                }
120        }
121
122        static inline lock_scope(L) lock( L * locks [], size_t count, lock_scope(L) & scope) {
123                lock(locks, count);
124                scope.locks = locks;
125                scope.count = count;
126        }
127
128        static inline void unlock( lock_scope(L) & this ) {
129                unlock(this.locks, this.count);
130                this.count = 0;
131        }
132
133        static inline void release( lock_scope(L) & this ) {
134                this.count = 0;
135        }
136        #else
137        void lock( [L &...] locks );
138        void unlock( [L &...] locks );
139
140        forall(size_t N)
141        struct lock_scope {
142                bool released;
143                [L &... N] locks;
144        };
145
146        void ?{}(lock_scope(L) & this) = void;
147        void ?{}(lock_scope(L) & this, lock_scope(L) other) = void;
148        void ?move?(lock_scope(L) & this, lock_scope(L) & other) = default;
149
150        static inline void ^?{}(lock_scope(L) & this) {
151                if( !this.released ) {
152                        unlock(this.locks);
153                }
154        }
155
156        forall(size_t N)
157        static inline lock_scope(L, N) lock( [L &...] locks ) {
158                lock(locks);
159                return @{false, locks};
160        }
161
162        static inline void unlock( lock_scope(L) & this ) {
163                unlock(this.locks);
164                this.released = true
165        }
166
167        static inline void release( lock_scope(L) & this ) {
168                this.released = true;
169        }
170        #endif
171}
Note: See TracBrowser for help on using the repository browser.