- File:
-
- 1 edited
-
src/libcfa/concurrency/monitor.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
rcb0e6de r17af7d1 19 19 #include "kernel_private.h" 20 20 21 extern "C" { 22 void __enter_monitor_desc(monitor_desc * this) { 23 lock( &this->lock ); 24 thread_desc * thrd = this_thread(); 21 void enter(monitor_desc * this) { 22 lock( &this->lock ); 23 thread_desc * thrd = this_thread(); 25 24 26 if( !this->owner ) {27 //No one has the monitor, just take it28 this->owner = thrd;29 this->recursion = 1;30 }31 else if( this->owner == thrd) {32 //We already have the monitor, just not how many times we took it33 assert( this->recursion > 0 );34 this->recursion += 1;35 }36 else {37 //Some one else has the monitor, wait in line for it38 append( &this->entry_queue, thrd );39 ScheduleInternal( &this->lock );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 ); 40 39 41 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 42 return; 43 } 44 45 unlock( &this->lock ); 40 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 41 return; 46 42 } 47 43 48 void __leave_monitor_desc(monitor_desc * this) {49 lock( &this->lock ); 44 unlock( &this->lock ); 45 } 50 46 51 thread_desc * thrd = this_thread(); 52 assert( thrd == this->owner);47 void leave(monitor_desc * this) { 48 lock( &this->lock ); 53 49 54 //Leaving a recursion level, decrement the counter55 this->recursion -= 1;50 thread_desc * thrd = this_thread(); 51 assert( thrd == this->owner ); 56 52 57 //If we left the last level of recursion it means we are changing who owns the monitor 58 thread_desc * new_owner = 0; 59 if( this->recursion == 0) { 60 //Get the next thread in the list 61 new_owner = this->owner = pop_head( &this->entry_queue ); 53 //Leaving a recursion level, decrement the counter 54 this->recursion -= 1; 62 55 63 //We are passing the monitor to someone else, which means recursion level is not 0 64 this->recursion = new_owner ? 1 : 0; 65 } 56 //If we left the last level of recursion it means we are changing who owns the monitor 57 thread_desc * 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 ); 66 61 67 unlock( &this->lock ); 62 //We are passing the monitor to someone else, which means recursion level is not 0 63 this->recursion = new_owner ? 1 : 0; 64 } 68 65 69 //If we have a new owner, we need to wake-up the thread 70 if( new_owner ) { 71 ScheduleThread( new_owner ); 72 } 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 ); 73 71 } 74 72 } … … 76 74 void enter(monitor_desc ** monitors, int count) { 77 75 for(int i = 0; i < count; i++) { 78 __enter_monitor_desc( monitors[i] );76 enter( monitors[i] ); 79 77 } 80 78 } … … 82 80 void leave(monitor_desc ** monitors, int count) { 83 81 for(int i = count - 1; i >= 0; i--) { 84 __leave_monitor_desc( monitors[i] );82 leave( monitors[i] ); 85 83 } 86 84 }
Note:
See TracChangeset
for help on using the changeset viewer.