source: libcfa/src/concurrency/monitor.hfa @ cdacb73

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since cdacb73 was 77a2994, checked in by Thierry Delisle <tdelisle@…>, 4 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.