source: libcfa/src/concurrency/monitor.hfa@ 9082e0f1

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 9082e0f1 was 77a2994, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Implemented joining of threads.
It behaves very similarly to monitor destructors.

  • Property mode set to 100644
File size: 3.8 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 : Wed Dec 4 07:55:32 2019
13// Update Count : 11
14//
15
16#pragma once
17
18#include <stddef.h>
19
20#include <assert.h>
21#include "invoke.h"
22#include "stdlib.hfa"
23
24trait is_monitor(dtype T) {
25 $monitor * get_monitor( T & );
26 void ^?{}( T & mutex );
27};
28
29static inline void ?{}($monitor & this) with( this ) {
30 lock{};
31 entry_queue{};
32 signal_stack{};
33 owner = 0p;
34 recursion = 0;
35 mask.accepted = 0p;
36 mask.data = 0p;
37 mask.size = 0;
38 dtor_node = 0p;
39}
40
41static inline void ^?{}($monitor & ) {}
42
43struct monitor_guard_t {
44 $monitor ** m;
45 __lock_size_t count;
46 __monitor_group_t prev;
47};
48
49void ?{}( monitor_guard_t & this, $monitor ** m, __lock_size_t count, void (*func)() );
50void ^?{}( monitor_guard_t & this );
51
52struct monitor_dtor_guard_t {
53 $monitor * m;
54 __monitor_group_t prev;
55 bool join;
56};
57
58void ?{}( monitor_dtor_guard_t & this, $monitor ** m, void (*func)(), bool join );
59void ^?{}( monitor_dtor_guard_t & this );
60
61static inline forall( dtype T | sized(T) | { void ^?{}( T & mutex ); } )
62void delete( T * th ) {
63 ^(*th){};
64 free( th );
65}
66
67//-----------------------------------------------------------------------------
68// Internal scheduling
69
70struct __condition_criterion_t {
71 // Whether or not the criterion is met (True if met)
72 bool ready;
73
74 // The monitor this criterion concerns
75 $monitor * target;
76
77 // The parent node to which this criterion belongs
78 struct __condition_node_t * owner;
79
80 // Intrusive linked list Next field
81 __condition_criterion_t * next;
82};
83
84static inline __condition_criterion_t * & get_next( __condition_criterion_t & this ) {
85 return this.next;
86}
87
88struct __condition_node_t {
89 // Thread that needs to be woken when all criteria are met
90 $thread * waiting_thread;
91
92 // Array of criteria (Criterions are contiguous in memory)
93 __condition_criterion_t * criteria;
94
95 // Number of criterions in the criteria
96 __lock_size_t count;
97
98 // Intrusive linked list Next field
99 __condition_node_t * next;
100
101 // Custom user info accessible before signalling
102 uintptr_t user_info;
103};
104
105static inline __condition_node_t * & get_next( __condition_node_t & this ) {
106 return this.next;
107}
108
109void ?{}(__condition_node_t & this, $thread * waiting_thread, __lock_size_t count, uintptr_t user_info );
110void ?{}(__condition_criterion_t & this );
111void ?{}(__condition_criterion_t & this, $monitor * target, __condition_node_t * owner );
112
113struct condition {
114 // Link list which contains the blocked threads as-well as the information needed to unblock them
115 __queue_t(__condition_node_t) blocked;
116
117 // Array of monitor pointers (Monitors are NOT contiguous in memory)
118 $monitor ** monitors;
119
120 // Number of monitors in the array
121 __lock_size_t monitor_count;
122};
123
124static inline void ?{}( condition & this ) {
125 this.monitors = 0p;
126 this.monitor_count = 0;
127}
128
129static inline void ^?{}( condition & this ) {
130 free( this.monitors );
131}
132
133 void wait ( condition & this, uintptr_t user_info = 0 );
134 bool signal ( condition & this );
135 bool signal_block( condition & this );
136static inline bool is_empty ( condition & this ) { return this.blocked.head == 1p; }
137 uintptr_t front ( condition & this );
138
139//-----------------------------------------------------------------------------
140// External scheduling
141
142struct __acceptable_t {
143 inline struct __monitor_group_t;
144 bool is_dtor;
145};
146
147void __waitfor_internal( const __waitfor_mask_t & mask, int duration );
148
149// Local Variables: //
150// mode: c //
151// tab-width: 4 //
152// End: //
Note: See TracBrowser for help on using the repository browser.