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

ADT ast-experimental
Last change on this file since fbdfcd8 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
RevLine 
[f07e037]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
[91c389a]11// Last Modified By : Peter A. Buhr
[8a97248]12// Last Modified On : Thu Feb 2 11:29:21 2023
13// Update Count : 12
[f07e037]14//
15
[6b0b624]16#pragma once
[f07e037]17
[690f13c]18#include <stddef.h>
19
[91c389a]20#include <assert.h>
[f07e037]21#include "invoke.h"
[58b6d1b]22#include "stdlib.hfa"
[f07e037]23
[8a97248]24forall( T & )
25trait is_monitor {
[e84ab3d]26 monitor$ * get_monitor( T & );
[1dcd9554]27 void ^?{}( T & mutex );
28};
29
[e84ab3d]30static inline void ?{}(monitor$ & this) with( this ) {
[c40e7c5]31 lock{};
32 entry_queue{};
33 signal_stack{};
[121be3e]34 owner = 0p;
[c40e7c5]35 recursion = 0;
[121be3e]36 mask.accepted = 0p;
37 mask.data = 0p;
[c40e7c5]38 mask.size = 0;
[121be3e]39 dtor_node = 0p;
[cc7f4b1]40}
41
[e84ab3d]42static inline void ^?{}(monitor$ & ) {}
[6c3a5ac1]43
[cc7f4b1]44struct monitor_guard_t {
[e84ab3d]45 monitor$ ** m;
[0cf5b79]46 __lock_size_t count;
47 __monitor_group_t prev;
[51f3798]48};
49
[e84ab3d]50void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count, void (*func)() );
[6cebfef]51void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count );
[242a902]52void ^?{}( monitor_guard_t & this );
[51f3798]53
[549c006]54struct monitor_dtor_guard_t {
[e84ab3d]55 monitor$ * m;
[0cf5b79]56 __monitor_group_t prev;
[77a2994]57 bool join;
[549c006]58};
59
[e84ab3d]60void ?{}( monitor_dtor_guard_t & this, monitor$ ** m, void (*func)(), bool join );
[549c006]61void ^?{}( monitor_dtor_guard_t & this );
62
[ef1da0e2]63/*
[fd54fef]64static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } )
[751d963]65void delete( T * th ) {
[e0b8d66d]66 if(th) ^(*th){};
[751d963]67 free( th );
68}
[ef1da0e2]69*/
[751d963]70
[a1574e2]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
[5ea06d6]82//-----------------------------------------------------------------------------
83// Internal scheduling
[0c78741]84
85struct __condition_criterion_t {
[025278e]86 // Whether or not the criterion is met (True if met)
87 bool ready;
88
89 // The monitor this criterion concerns
[e84ab3d]90 monitor$ * target;
[025278e]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;
[0c78741]97};
98
[0cf5b79]99static inline __condition_criterion_t * & get_next( __condition_criterion_t & this ) {
100 return this.next;
101}
102
[0c78741]103struct __condition_node_t {
[025278e]104 // Thread that needs to be woken when all criteria are met
[e84ab3d]105 thread$ * waiting_thread;
[025278e]106
107 // Array of criteria (Criterions are contiguous in memory)
108 __condition_criterion_t * criteria;
109
110 // Number of criterions in the criteria
[c1a9c86]111 __lock_size_t count;
[025278e]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;
[0c78741]118};
119
[0cf5b79]120static inline __condition_node_t * & get_next( __condition_node_t & this ) {
121 return this.next;
122}
[0c78741]123
[c18bf9e]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 );
[e5c8488]127
[5ea06d6]128struct condition {
[025278e]129 // Link list which contains the blocked threads as-well as the information needed to unblock them
[0cf5b79]130 __queue_t(__condition_node_t) blocked;
[025278e]131
132 // Array of monitor pointers (Monitors are NOT contiguous in memory)
[e84ab3d]133 monitor$ ** monitors;
[025278e]134
135 // Number of monitors in the array
[c1a9c86]136 __lock_size_t monitor_count;
[5ea06d6]137};
[51f3798]138
[242a902]139static inline void ?{}( condition & this ) {
[121be3e]140 this.monitors = 0p;
[242a902]141 this.monitor_count = 0;
[5ea06d6]142}
[2781e65]143
[242a902]144static inline void ^?{}( condition & this ) {
145 free( this.monitors );
[1167cd4]146}
147
[8fc45b7]148 void wait ( condition & this, uintptr_t user_info = 0 );
[1f58c62]149static inline bool is_empty ( condition & this ) { return this.blocked.head == 1p; }
[8fc45b7]150 bool signal ( condition & this );
151 bool signal_block( condition & this );
[1f58c62]152static inline bool signal_all ( condition & this ) { bool ret = false; while(!is_empty(this)) { ret = signal(this) || ret; } return ret; }
[8fc45b7]153 uintptr_t front ( condition & this );
[be3d020]154
[97e3296]155//-----------------------------------------------------------------------------
156// External scheduling
157
[c81ebf9]158struct __acceptable_t {
[b1672e1]159 inline struct __monitor_group_t;
[9f5ecf5]160 bool is_dtor;
[c81ebf9]161};
162
[6ae8c92]163void __waitfor_internal( const __waitfor_mask_t & mask, int duration );
[c81ebf9]164
[af67ee1]165// lock and unlock routines for mutex statements to use
166void lock( monitor$ * this );
167void unlock( monitor$ * this );
168
[6b0b624]169// Local Variables: //
170// mode: c //
171// tab-width: 4 //
[8a97248]172// End: //
Note: See TracBrowser for help on using the repository browser.