source: src/libcfa/concurrency/monitor.c@ 3f80888

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 3f80888 was 2781e65, checked in by Thierry Delisle <tdelisle@…>, 9 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.