source: src/libcfa/concurrency/monitor.c @ cc7f4b1

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since cc7f4b1 was cc7f4b1, checked in by Thierry Delisle <tdelisle@…>, 7 years ago
  • renamed monitor to monitor_t since the type should not be exposed to users
  • added support for recursion in monitors
  • Property mode set to 100644
File size: 1.8 KB
RevLine 
[f07e037]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//
[cc7f4b1]8// __monitor_t.c --
[f07e037]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
[cc7f4b1]21void enter(__monitor_t * this) {
[f07e037]22        lock( &this->lock );
23        thread * thrd = this_thread();
24
[cc7f4b1]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;
[f07e037]34        }
35        else {
[cc7f4b1]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; 
[f07e037]42        }
43
44        unlock( &this->lock );
45}
46
[cc7f4b1]47void leave(__monitor_t * this) {
[f07e037]48        lock( &this->lock );
49
50        thread * thrd = this_thread();
[cc7f4b1]51        assert( thrd == this->owner );
52
53        //Leaving a recursion level, decrement the counter
54        this->recursion -= 1;
[f07e037]55
[cc7f4b1]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        }       
[f07e037]65
66        unlock( &this->lock );
[51f3798]67
[cc7f4b1]68        //If we have a new owner, we need to wake-up the thread
69        if( new_owner ) {
70                ScheduleThread( new_owner );
71        }
[f07e037]72}
Note: See TracBrowser for help on using the repository browser.