- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
r4aa2fb2 rb227f68 19 19 #include <stdlib> 20 20 21 #include "libhdr.h" 21 22 #include "kernel_private.h" 22 #include "libhdr.h"23 23 24 24 //----------------------------------------------------------------------------- … … 44 44 45 45 extern "C" { 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);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); 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 ScheduleInternal( &this->lock );66 67 // ScheduleInternal will unlock spinlock, no need to unlock ourselves68 return; 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 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 ( &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 );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 ); 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 ScheduleThread( new_owner ); 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 ); 102 131 } 103 132 } … … 121 150 enter( this->m, this->count ); 122 151 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;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; 128 157 } 129 158 … … 131 160 leave( this->m, this->count ); 132 161 133 this_thread ()->current_monitors = this->prev_mntrs;134 this_thread ()->current_monitor_count = this->prev_count;162 this_thread->current_monitors = this->prev_mntrs; 163 this_thread->current_monitor_count = this->prev_count; 135 164 } 136 165 … … 159 188 // Internal scheduling 160 189 void wait( condition * this, uintptr_t user_info = 0 ) { 161 LIB_DEBUG_PRINT_SAFE("Waiting\n");190 // LIB_DEBUG_PRINT_SAFE("Waiting\n"); 162 191 163 192 brand_condition( this ); … … 170 199 unsigned short count = this->monitor_count; 171 200 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 172 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal173 174 LIB_DEBUG_PRINT_SAFE("count %i\n", count);175 176 __condition_node_t waiter = { this_thread(), count, user_info };201 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 202 203 // LIB_DEBUG_PRINT_SAFE("count %i\n", count); 204 205 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info }; 177 206 178 207 __condition_criterion_t criteria[count]; 179 208 for(int i = 0; i < count; i++) { 180 209 (&criteria[i]){ this->monitors[i], &waiter }; 181 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );210 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 182 211 } 183 212 … … 201 230 } 202 231 203 LIB_DEBUG_PRINT_SAFE("Will unblock: ");232 // LIB_DEBUG_PRINT_SAFE("Will unblock: "); 204 233 for(int i = 0; i < thread_count; i++) { 205 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);206 } 207 LIB_DEBUG_PRINT_SAFE("\n");234 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 235 } 236 // LIB_DEBUG_PRINT_SAFE("\n"); 208 237 209 238 // Everything is ready to go to sleep 210 ScheduleInternal( locks, count, threads, thread_count );239 BlockInternal( locks, count, threads, thread_count ); 211 240 212 241 … … 222 251 bool signal( condition * this ) { 223 252 if( is_empty( this ) ) { 224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");253 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 225 254 return false; 226 255 } … … 231 260 232 261 unsigned short count = this->monitor_count; 233 262 234 263 //Some more checking in debug 235 264 LIB_DEBUG_DO( 236 thread_desc * this_thrd = this_thread ();265 thread_desc * this_thrd = this_thread; 237 266 if ( this->monitor_count != this_thrd->current_monitor_count ) { 238 267 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 ); … … 248 277 //Lock all the monitors 249 278 lock_all( this->monitors, NULL, count ); 250 LIB_DEBUG_PRINT_SAFE("Signalling");279 // LIB_DEBUG_PRINT_SAFE("Signalling"); 251 280 252 281 //Pop the head of the waiting queue … … 256 285 for(int i = 0; i < count; i++) { 257 286 __condition_criterion_t * crit = &node->criteria[i]; 258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);287 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 259 288 assert( !crit->ready ); 260 289 push( &crit->target->signal_stack, crit ); 261 290 } 262 291 263 LIB_DEBUG_PRINT_SAFE("\n");292 // LIB_DEBUG_PRINT_SAFE("\n"); 264 293 265 294 //Release … … 281 310 unsigned short count = this->monitor_count; 282 311 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 283 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal312 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 284 313 285 314 lock_all( this->monitors, locks, count ); 286 315 287 316 //create creteria 288 __condition_node_t waiter = { this_thread(), count, 0 };317 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 }; 289 318 290 319 __condition_criterion_t criteria[count]; 291 320 for(int i = 0; i < count; i++) { 292 321 (&criteria[i]){ this->monitors[i], &waiter }; 293 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );322 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 294 323 push( &criteria[i].target->signal_stack, &criteria[i] ); 295 324 } … … 309 338 310 339 //Everything is ready to go to sleep 311 ScheduleInternal( locks, count, &signallee, 1 );340 BlockInternal( locks, count, &signallee, 1 ); 312 341 313 342 … … 325 354 326 355 uintptr_t front( condition * this ) { 327 verifyf( !is_empty(this), 356 verifyf( !is_empty(this), 328 357 "Attempt to access user data on an empty condition.\n" 329 358 "Possible cause is not checking if the condition is empty before reading stored data." … … 335 364 // Internal scheduling 336 365 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 337 // thread_desc * this = this_thread ();366 // thread_desc * this = this_thread; 338 367 339 368 // unsigned short count = this->current_monitor_count; 340 369 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal370 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 342 371 343 372 // lock_all( this->current_monitors, locks, count ); … … 348 377 349 378 // // // Everything is ready to go to sleep 350 // // ScheduleInternal( locks, count, threads, thread_count );379 // // BlockInternal( locks, count, threads, thread_count ); 351 380 352 381 … … 393 422 static inline void lock_all( spinlock ** locks, unsigned short count ) { 394 423 for( int i = 0; i < count; i++ ) { 395 lock ( locks[i]);424 lock_yield( locks[i] DEBUG_CTX2 ); 396 425 } 397 426 } … … 400 429 for( int i = 0; i < count; i++ ) { 401 430 spinlock * l = &source[i]->lock; 402 lock ( l);431 lock_yield( l DEBUG_CTX2 ); 403 432 if(locks) locks[i] = l; 404 433 } … … 443 472 for( int i = 0; i < count; i++ ) { 444 473 445 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );474 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 446 475 if( &criteria[i] == target ) { 447 476 criteria[i].ready = true; 448 LIB_DEBUG_PRINT_SAFE( "True\n" );477 // LIB_DEBUG_PRINT_SAFE( "True\n" ); 449 478 } 450 479 … … 452 481 } 453 482 454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );483 // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 455 484 return ready2run ? node->waiting_thread : NULL; 456 485 } 457 486 458 487 static inline void brand_condition( condition * this ) { 459 thread_desc * thrd = this_thread ();488 thread_desc * thrd = this_thread; 460 489 if( !this->monitors ) { 461 LIB_DEBUG_PRINT_SAFE("Branding\n");490 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 462 491 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 463 492 this->monitor_count = thrd->current_monitor_count;
Note: See TracChangeset
for help on using the changeset viewer.