- File:
-
- 1 edited
-
src/libcfa/concurrency/monitor.c (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
rb227f68 r4aa2fb2 19 19 #include <stdlib> 20 20 21 #include "kernel_private.h" 21 22 #include "libhdr.h" 22 #include "kernel_private.h"23 23 24 24 //----------------------------------------------------------------------------- … … 44 44 45 45 extern "C" { 46 void __enter_monitor_desc( monitor_desc * this) {47 lock _yield( &this->lock DEBUG_CTX2);48 thread_desc * thrd = this_thread ;49 50 //LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);46 void __enter_monitor_desc(monitor_desc * this) { 47 lock( &this->lock ); 48 thread_desc * thrd = this_thread(); 49 50 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 51 51 52 52 if( !this->owner ) { … … 62 62 //Some one else has the monitor, wait in line for it 63 63 append( &this->entry_queue, thrd ); 64 //LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);65 BlockInternal( &this->lock );66 67 // BlockInternal will unlock spinlock, no need to unlock ourselves68 return; 64 LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 65 ScheduleInternal( &this->lock ); 66 67 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 68 return; 69 69 } 70 70 … … 75 75 // leave pseudo code : 76 76 // TODO 77 void __leave_monitor_desc( monitor_desc * this) {78 lock _yield( &this->lock DEBUG_CTX2);79 80 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);81 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );77 void __leave_monitor_desc(monitor_desc * this) { 78 lock( &this->lock ); 79 80 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 81 verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion ); 82 82 83 83 //Leaving a recursion level, decrement the counter … … 96 96 unlock( &this->lock ); 97 97 98 //LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);98 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner); 99 99 100 100 //We need to wake-up the thread 101 WakeThread( new_owner ); 102 } 103 104 void __leave_thread_monitor( thread_desc * thrd ) { 105 monitor_desc * this = &thrd->mon; 106 lock_yield( &this->lock DEBUG_CTX2 ); 107 108 disable_interrupts(); 109 110 thrd->cor.state = Halted; 111 112 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 113 114 //Leaving a recursion level, decrement the counter 115 this->recursion -= 1; 116 117 //If we haven't left the last level of recursion 118 //it means we don't need to do anything 119 if( this->recursion != 0) { 120 unlock( &this->lock ); 121 return; 122 } 123 124 thread_desc * new_owner = next_thread( this ); 125 126 //We can now let other threads in safely 127 unlock( &this->lock ); 128 129 //We need to wake-up the thread 130 if( new_owner) ScheduleThread( new_owner ); 101 ScheduleThread( new_owner ); 131 102 } 132 103 } … … 150 121 enter( this->m, this->count ); 151 122 152 this->prev_mntrs = this_thread ->current_monitors;153 this->prev_count = this_thread ->current_monitor_count;154 155 this_thread ->current_monitors = m;156 this_thread ->current_monitor_count = count;123 this->prev_mntrs = this_thread()->current_monitors; 124 this->prev_count = this_thread()->current_monitor_count; 125 126 this_thread()->current_monitors = m; 127 this_thread()->current_monitor_count = count; 157 128 } 158 129 … … 160 131 leave( this->m, this->count ); 161 132 162 this_thread ->current_monitors = this->prev_mntrs;163 this_thread ->current_monitor_count = this->prev_count;133 this_thread()->current_monitors = this->prev_mntrs; 134 this_thread()->current_monitor_count = this->prev_count; 164 135 } 165 136 … … 188 159 // Internal scheduling 189 160 void wait( condition * this, uintptr_t user_info = 0 ) { 190 //LIB_DEBUG_PRINT_SAFE("Waiting\n");161 LIB_DEBUG_PRINT_SAFE("Waiting\n"); 191 162 192 163 brand_condition( this ); … … 199 170 unsigned short count = this->monitor_count; 200 171 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 201 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal202 203 //LIB_DEBUG_PRINT_SAFE("count %i\n", count);204 205 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };172 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 173 174 LIB_DEBUG_PRINT_SAFE("count %i\n", count); 175 176 __condition_node_t waiter = { this_thread(), count, user_info }; 206 177 207 178 __condition_criterion_t criteria[count]; 208 179 for(int i = 0; i < count; i++) { 209 180 (&criteria[i]){ this->monitors[i], &waiter }; 210 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );181 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 211 182 } 212 183 … … 230 201 } 231 202 232 //LIB_DEBUG_PRINT_SAFE("Will unblock: ");203 LIB_DEBUG_PRINT_SAFE("Will unblock: "); 233 204 for(int i = 0; i < thread_count; i++) { 234 //LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);235 } 236 //LIB_DEBUG_PRINT_SAFE("\n");205 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 206 } 207 LIB_DEBUG_PRINT_SAFE("\n"); 237 208 238 209 // Everything is ready to go to sleep 239 BlockInternal( locks, count, threads, thread_count );210 ScheduleInternal( locks, count, threads, thread_count ); 240 211 241 212 … … 251 222 bool signal( condition * this ) { 252 223 if( is_empty( this ) ) { 253 //LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 254 225 return false; 255 226 } … … 260 231 261 232 unsigned short count = this->monitor_count; 262 233 263 234 //Some more checking in debug 264 235 LIB_DEBUG_DO( 265 thread_desc * this_thrd = this_thread ;236 thread_desc * this_thrd = this_thread(); 266 237 if ( this->monitor_count != this_thrd->current_monitor_count ) { 267 238 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); … … 277 248 //Lock all the monitors 278 249 lock_all( this->monitors, NULL, count ); 279 //LIB_DEBUG_PRINT_SAFE("Signalling");250 LIB_DEBUG_PRINT_SAFE("Signalling"); 280 251 281 252 //Pop the head of the waiting queue … … 285 256 for(int i = 0; i < count; i++) { 286 257 __condition_criterion_t * crit = &node->criteria[i]; 287 //LIB_DEBUG_PRINT_SAFE(" %p", crit->target);258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 288 259 assert( !crit->ready ); 289 260 push( &crit->target->signal_stack, crit ); 290 261 } 291 262 292 //LIB_DEBUG_PRINT_SAFE("\n");263 LIB_DEBUG_PRINT_SAFE("\n"); 293 264 294 265 //Release … … 310 281 unsigned short count = this->monitor_count; 311 282 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 312 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal283 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 313 284 314 285 lock_all( this->monitors, locks, count ); 315 286 316 287 //create creteria 317 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };288 __condition_node_t waiter = { this_thread(), count, 0 }; 318 289 319 290 __condition_criterion_t criteria[count]; 320 291 for(int i = 0; i < count; i++) { 321 292 (&criteria[i]){ this->monitors[i], &waiter }; 322 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );293 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 323 294 push( &criteria[i].target->signal_stack, &criteria[i] ); 324 295 } … … 338 309 339 310 //Everything is ready to go to sleep 340 BlockInternal( locks, count, &signallee, 1 );311 ScheduleInternal( locks, count, &signallee, 1 ); 341 312 342 313 … … 354 325 355 326 uintptr_t front( condition * this ) { 356 verifyf( !is_empty(this), 327 verifyf( !is_empty(this), 357 328 "Attempt to access user data on an empty condition.\n" 358 329 "Possible cause is not checking if the condition is empty before reading stored data." … … 364 335 // Internal scheduling 365 336 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 366 // thread_desc * this = this_thread ;337 // thread_desc * this = this_thread(); 367 338 368 339 // unsigned short count = this->current_monitor_count; 369 340 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 370 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 371 342 372 343 // lock_all( this->current_monitors, locks, count ); … … 377 348 378 349 // // // Everything is ready to go to sleep 379 // // BlockInternal( locks, count, threads, thread_count );350 // // ScheduleInternal( locks, count, threads, thread_count ); 380 351 381 352 … … 422 393 static inline void lock_all( spinlock ** locks, unsigned short count ) { 423 394 for( int i = 0; i < count; i++ ) { 424 lock _yield( locks[i] DEBUG_CTX2);395 lock( locks[i] ); 425 396 } 426 397 } … … 429 400 for( int i = 0; i < count; i++ ) { 430 401 spinlock * l = &source[i]->lock; 431 lock _yield( l DEBUG_CTX2);402 lock( l ); 432 403 if(locks) locks[i] = l; 433 404 } … … 472 443 for( int i = 0; i < count; i++ ) { 473 444 474 //LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );445 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 475 446 if( &criteria[i] == target ) { 476 447 criteria[i].ready = true; 477 //LIB_DEBUG_PRINT_SAFE( "True\n" );448 LIB_DEBUG_PRINT_SAFE( "True\n" ); 478 449 } 479 450 … … 481 452 } 482 453 483 //LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 484 455 return ready2run ? node->waiting_thread : NULL; 485 456 } 486 457 487 458 static inline void brand_condition( condition * this ) { 488 thread_desc * thrd = this_thread ;459 thread_desc * thrd = this_thread(); 489 460 if( !this->monitors ) { 490 //LIB_DEBUG_PRINT_SAFE("Branding\n");461 LIB_DEBUG_PRINT_SAFE("Branding\n"); 491 462 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 492 463 this->monitor_count = thrd->current_monitor_count;
Note:
See TracChangeset
for help on using the changeset viewer.