- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
rf2b12406 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 LeaveThread( &this->lock, new_owner ); 101 ScheduleThread( new_owner ); 127 102 } 128 103 } … … 146 121 enter( this->m, this->count ); 147 122 148 this->prev_mntrs = this_thread ->current_monitors;149 this->prev_count = this_thread ->current_monitor_count;150 151 this_thread ->current_monitors = m;152 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; 153 128 } 154 129 … … 156 131 leave( this->m, this->count ); 157 132 158 this_thread ->current_monitors = this->prev_mntrs;159 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; 160 135 } 161 136 … … 184 159 // Internal scheduling 185 160 void wait( condition * this, uintptr_t user_info = 0 ) { 186 //LIB_DEBUG_PRINT_SAFE("Waiting\n");161 LIB_DEBUG_PRINT_SAFE("Waiting\n"); 187 162 188 163 brand_condition( this ); … … 195 170 unsigned short count = this->monitor_count; 196 171 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 197 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal198 199 //LIB_DEBUG_PRINT_SAFE("count %i\n", count);200 201 __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 }; 202 177 203 178 __condition_criterion_t criteria[count]; 204 179 for(int i = 0; i < count; i++) { 205 180 (&criteria[i]){ this->monitors[i], &waiter }; 206 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );181 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 207 182 } 208 183 … … 226 201 } 227 202 228 //LIB_DEBUG_PRINT_SAFE("Will unblock: ");203 LIB_DEBUG_PRINT_SAFE("Will unblock: "); 229 204 for(int i = 0; i < thread_count; i++) { 230 //LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);231 } 232 //LIB_DEBUG_PRINT_SAFE("\n");205 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 206 } 207 LIB_DEBUG_PRINT_SAFE("\n"); 233 208 234 209 // Everything is ready to go to sleep 235 BlockInternal( locks, count, threads, thread_count );210 ScheduleInternal( locks, count, threads, thread_count ); 236 211 237 212 … … 247 222 bool signal( condition * this ) { 248 223 if( is_empty( this ) ) { 249 //LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 250 225 return false; 251 226 } … … 256 231 257 232 unsigned short count = this->monitor_count; 258 233 259 234 //Some more checking in debug 260 235 LIB_DEBUG_DO( 261 thread_desc * this_thrd = this_thread ;236 thread_desc * this_thrd = this_thread(); 262 237 if ( this->monitor_count != this_thrd->current_monitor_count ) { 263 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 ); … … 273 248 //Lock all the monitors 274 249 lock_all( this->monitors, NULL, count ); 275 //LIB_DEBUG_PRINT_SAFE("Signalling");250 LIB_DEBUG_PRINT_SAFE("Signalling"); 276 251 277 252 //Pop the head of the waiting queue … … 281 256 for(int i = 0; i < count; i++) { 282 257 __condition_criterion_t * crit = &node->criteria[i]; 283 //LIB_DEBUG_PRINT_SAFE(" %p", crit->target);258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 284 259 assert( !crit->ready ); 285 260 push( &crit->target->signal_stack, crit ); 286 261 } 287 262 288 //LIB_DEBUG_PRINT_SAFE("\n");263 LIB_DEBUG_PRINT_SAFE("\n"); 289 264 290 265 //Release … … 306 281 unsigned short count = this->monitor_count; 307 282 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 308 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 309 284 310 285 lock_all( this->monitors, locks, count ); 311 286 312 287 //create creteria 313 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };288 __condition_node_t waiter = { this_thread(), count, 0 }; 314 289 315 290 __condition_criterion_t criteria[count]; 316 291 for(int i = 0; i < count; i++) { 317 292 (&criteria[i]){ this->monitors[i], &waiter }; 318 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );293 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 319 294 push( &criteria[i].target->signal_stack, &criteria[i] ); 320 295 } … … 334 309 335 310 //Everything is ready to go to sleep 336 BlockInternal( locks, count, &signallee, 1 );311 ScheduleInternal( locks, count, &signallee, 1 ); 337 312 338 313 … … 350 325 351 326 uintptr_t front( condition * this ) { 352 verifyf( !is_empty(this), 327 verifyf( !is_empty(this), 353 328 "Attempt to access user data on an empty condition.\n" 354 329 "Possible cause is not checking if the condition is empty before reading stored data." … … 360 335 // Internal scheduling 361 336 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 362 // thread_desc * this = this_thread ;337 // thread_desc * this = this_thread(); 363 338 364 339 // unsigned short count = this->current_monitor_count; 365 340 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 366 // 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 367 342 368 343 // lock_all( this->current_monitors, locks, count ); … … 373 348 374 349 // // // Everything is ready to go to sleep 375 // // BlockInternal( locks, count, threads, thread_count );350 // // ScheduleInternal( locks, count, threads, thread_count ); 376 351 377 352 … … 418 393 static inline void lock_all( spinlock ** locks, unsigned short count ) { 419 394 for( int i = 0; i < count; i++ ) { 420 lock _yield( locks[i] DEBUG_CTX2);395 lock( locks[i] ); 421 396 } 422 397 } … … 425 400 for( int i = 0; i < count; i++ ) { 426 401 spinlock * l = &source[i]->lock; 427 lock _yield( l DEBUG_CTX2);402 lock( l ); 428 403 if(locks) locks[i] = l; 429 404 } … … 468 443 for( int i = 0; i < count; i++ ) { 469 444 470 //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 ); 471 446 if( &criteria[i] == target ) { 472 447 criteria[i].ready = true; 473 //LIB_DEBUG_PRINT_SAFE( "True\n" );448 LIB_DEBUG_PRINT_SAFE( "True\n" ); 474 449 } 475 450 … … 477 452 } 478 453 479 //LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 480 455 return ready2run ? node->waiting_thread : NULL; 481 456 } 482 457 483 458 static inline void brand_condition( condition * this ) { 484 thread_desc * thrd = this_thread ;459 thread_desc * thrd = this_thread(); 485 460 if( !this->monitors ) { 486 //LIB_DEBUG_PRINT_SAFE("Branding\n");461 LIB_DEBUG_PRINT_SAFE("Branding\n"); 487 462 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 488 463 this->monitor_count = thrd->current_monitor_count;
Note:
See TracChangeset
for help on using the changeset viewer.