source: libcfa/src/concurrency/mutex.hfa

Last change on this file was 8a97248, checked in by Peter A. Buhr <pabuhr@…>, 14 months ago

switch from old trait syntax to new trait syntax using forall clause

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