source: libcfa/src/concurrency/monitor.hfa @ 3381ed7

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 3381ed7 was 3381ed7, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Added park/unpark primitives thread and removed BlockInternal?.
Converted monitors to use park unpark.
Intrusive Queue now mark next field when thread is inside queue.
Added several asserts to kernel and monitor.
Added a few tests for park and unpark.

  • 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_desc * get_monitor( T & );
26        void ^?{}( T & mutex );
27};
28
29static inline void ?{}(monitor_desc & this) with( this ) {
30        lock{};
31        entry_queue{};
32        signal_stack{};
33        owner         = 0p;
34        owner_reason  = __NO_OWNER;
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_desc & ) {}
43
44struct monitor_guard_t {
45        monitor_desc **         m;
46        __lock_size_t           count;
47        __monitor_group_t prev;
48};
49
50void ?{}( monitor_guard_t & this, monitor_desc ** m, __lock_size_t count, void (*func)() );
51void ^?{}( monitor_guard_t & this );
52
53struct monitor_dtor_guard_t {
54        monitor_desc *    m;
55        __monitor_group_t prev;
56};
57
58void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() );
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_desc * 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_desc * 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_desc * waiting_thread, __lock_size_t count, uintptr_t user_info );
110void ?{}(__condition_criterion_t & this );
111void ?{}(__condition_criterion_t & this, monitor_desc * 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_desc ** 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.