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

Last change on this file since a51dc0d was 8a97248, checked in by Peter A. Buhr <pabuhr@…>, 21 months 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.