source: libcfa/src/concurrency/monitor.hfa@ 03ac869

Last change on this file since 03ac869 was 8a97248, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

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

  • Property mode set to 100644
File size: 4.5 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// monitor --
8//
9// Author : Thierry Delisle
10// Created On : Thd Feb 23 12:27:26 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb 2 11:29:21 2023
13// Update Count : 12
14//
15
16#pragma once
17
18#include <stddef.h>
19
20#include <assert.h>
21#include "invoke.h"
22#include "stdlib.hfa"
23
24forall( T & )
25trait is_monitor {
26 monitor$ * get_monitor( T & );
27 void ^?{}( T & mutex );
28};
29
30static inline void ?{}(monitor$ & this) with( this ) {
31 lock{};
32 entry_queue{};
33 signal_stack{};
34 owner = 0p;
35 recursion = 0;
36 mask.accepted = 0p;
37 mask.data = 0p;
38 mask.size = 0;
39 dtor_node = 0p;
40}
41
42static inline void ^?{}(monitor$ & ) {}
43
44struct monitor_guard_t {
45 monitor$ ** m;
46 __lock_size_t count;
47 __monitor_group_t prev;
48};
49
50void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count, void (*func)() );
51void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count );
52void ^?{}( monitor_guard_t & this );
53
54struct monitor_dtor_guard_t {
55 monitor$ * m;
56 __monitor_group_t prev;
57 bool join;
58};
59
60void ?{}( monitor_dtor_guard_t & this, monitor$ ** m, void (*func)(), bool join );
61void ^?{}( monitor_dtor_guard_t & this );
62
63/*
64static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } )
65void delete( T * th ) {
66 if(th) ^(*th){};
67 free( th );
68}
69*/
70
71static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } )
72void adelete( T arr[] ) {
73 if ( arr ) { // ignore null
74 size_t dim = malloc_size( arr ) / sizeof( T );
75 for ( int i = dim - 1; i >= 0; i -= 1 ) { // reverse allocation order, must be unsigned
76 ^(arr[i]){}; // run destructor
77 } // for
78 free( arr );
79 } // if
80} // adelete
81
82//-----------------------------------------------------------------------------
83// Internal scheduling
84
85struct __condition_criterion_t {
86 // Whether or not the criterion is met (True if met)
87 bool ready;
88
89 // The monitor this criterion concerns
90 monitor$ * target;
91
92 // The parent node to which this criterion belongs
93 struct __condition_node_t * owner;
94
95 // Intrusive linked list Next field
96 __condition_criterion_t * next;
97};
98
99static inline __condition_criterion_t * & get_next( __condition_criterion_t & this ) {
100 return this.next;
101}
102
103struct __condition_node_t {
104 // Thread that needs to be woken when all criteria are met
105 thread$ * waiting_thread;
106
107 // Array of criteria (Criterions are contiguous in memory)
108 __condition_criterion_t * criteria;
109
110 // Number of criterions in the criteria
111 __lock_size_t count;
112
113 // Intrusive linked list Next field
114 __condition_node_t * next;
115
116 // Custom user info accessible before signalling
117 uintptr_t user_info;
118};
119
120static inline __condition_node_t * & get_next( __condition_node_t & this ) {
121 return this.next;
122}
123
124// void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info );
125// void ?{}(__condition_criterion_t & this );
126// void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t * owner );
127
128struct condition {
129 // Link list which contains the blocked threads as-well as the information needed to unblock them
130 __queue_t(__condition_node_t) blocked;
131
132 // Array of monitor pointers (Monitors are NOT contiguous in memory)
133 monitor$ ** monitors;
134
135 // Number of monitors in the array
136 __lock_size_t monitor_count;
137};
138
139static inline void ?{}( condition & this ) {
140 this.monitors = 0p;
141 this.monitor_count = 0;
142}
143
144static inline void ^?{}( condition & this ) {
145 free( this.monitors );
146}
147
148 void wait ( condition & this, uintptr_t user_info = 0 );
149static inline bool is_empty ( condition & this ) { return this.blocked.head == 1p; }
150 bool signal ( condition & this );
151 bool signal_block( condition & this );
152static inline bool signal_all ( condition & this ) { bool ret = false; while(!is_empty(this)) { ret = signal(this) || ret; } return ret; }
153 uintptr_t front ( condition & this );
154
155//-----------------------------------------------------------------------------
156// External scheduling
157
158struct __acceptable_t {
159 inline struct __monitor_group_t;
160 bool is_dtor;
161};
162
163void __waitfor_internal( const __waitfor_mask_t & mask, int duration );
164
165// lock and unlock routines for mutex statements to use
166void lock( monitor$ * this );
167void unlock( monitor$ * this );
168
169// Local Variables: //
170// mode: c //
171// tab-width: 4 //
172// End: //
Note: See TracBrowser for help on using the repository browser.