source: src/libcfa/concurrency/monitor.c @ 2781e65

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 2781e65 was 2781e65, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

added support for acquiring multiple monitors at once

  • Property mode set to 100644
File size: 2.0 KB
Line 
1//                              -*- Mode: CFA -*-
2//
3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
4//
5// The contents of this file are covered under the licence agreement in the
6// file "LICENCE" distributed with Cforall.
7//
8// __monitor_t.c --
9//
10// Author           : Thierry Delisle
11// Created On       : Thd Feb 23 12:27:26 2017
12// Last Modified By : Thierry Delisle
13// Last Modified On : --
14// Update Count     : 0
15//
16
17#include "monitor"
18
19#include "kernel_private.h"
20
21void enter(__monitor_t * this) {
22        lock( &this->lock );
23        thread * thrd = this_thread();
24
25        if( !this->owner ) {
26                //No one has the monitor, just take it
27                this->owner = thrd;
28                this->recursion = 1;
29        }
30        else if( this->owner == thrd) {
31                //We already have the monitor, just not how many times we took it
32                assert( this->recursion > 0 );
33                this->recursion += 1;
34        }
35        else {
36                //Some one else has the monitor, wait in line for it
37                append( &this->entry_queue, thrd );
38                ScheduleInternal( &this->lock );
39
40                //ScheduleInternal will unlock spinlock, no need to unlock ourselves
41                return; 
42        }
43
44        unlock( &this->lock );
45}
46
47void leave(__monitor_t * this) {
48        lock( &this->lock );
49
50        thread * thrd = this_thread();
51        assert( thrd == this->owner );
52
53        //Leaving a recursion level, decrement the counter
54        this->recursion -= 1;
55
56        //If we left the last level of recursion it means we are changing who owns the monitor
57        thread * new_owner = 0;
58        if( this->recursion == 0) {
59                //Get the next thread in the list
60                new_owner = this->owner = pop_head( &this->entry_queue );
61
62                //We are passing the monitor to someone else, which means recursion level is not 0
63                this->recursion = new_owner ? 1 : 0;
64        }       
65
66        unlock( &this->lock );
67
68        //If we have a new owner, we need to wake-up the thread
69        if( new_owner ) {
70                ScheduleThread( new_owner );
71        }
72}
73
74void enter(__monitor_t ** monitors, int count) {
75        for(int i = 0; i < count; i++) {
76                // printf("%d\n", i);
77                enter( monitors[i] );
78        }
79}
80
81void leave(__monitor_t ** monitors, int count) {
82        for(int i = count - 1; i >= 0; i--) {
83                // printf("%d\n", i);
84                leave( monitors[i] );
85        }
86}
Note: See TracBrowser for help on using the repository browser.