Changeset 4cedd9f for src/libcfa
- Timestamp:
- Nov 2, 2017, 2:15:19 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 8fc45b7
- Parents:
- e1e8408
- Location:
- src/libcfa/concurrency
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel
re1e8408 r4cedd9f 39 39 void ?{}(semaphore & this, int count = 1); 40 40 void ^?{}(semaphore & this); 41 void P(semaphore *this);42 void V(semaphore *this);41 void P (semaphore & this); 42 void V (semaphore & this); 43 43 44 44 … … 51 51 }; 52 52 53 void ?{} (cluster & this);53 void ?{} (cluster & this); 54 54 void ^?{}(cluster & this); 55 55 -
src/libcfa/concurrency/kernel.c
re1e8408 r4cedd9f 158 158 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this); 159 159 this.do_terminate = true; 160 P( &this.terminated );160 P( this.terminated ); 161 161 pthread_join( this.kernel_thread, NULL ); 162 162 } … … 216 216 } 217 217 218 V( &this->terminated );218 V( this->terminated ); 219 219 220 220 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this); … … 618 618 void ^?{}(semaphore & this) {} 619 619 620 void P(semaphore *this) {621 lock( &this ->lock DEBUG_CTX2 );622 this ->count -= 1;623 if ( this ->count < 0 ) {620 void P(semaphore & this) { 621 lock( &this.lock DEBUG_CTX2 ); 622 this.count -= 1; 623 if ( this.count < 0 ) { 624 624 // queue current task 625 append( &this ->waiting, (thread_desc *)this_thread );625 append( &this.waiting, (thread_desc *)this_thread ); 626 626 627 627 // atomically release spin lock and block 628 BlockInternal( &this ->lock );628 BlockInternal( &this.lock ); 629 629 } 630 630 else { 631 unlock( &this ->lock );632 } 633 } 634 635 void V(semaphore *this) {631 unlock( &this.lock ); 632 } 633 } 634 635 void V(semaphore & this) { 636 636 thread_desc * thrd = NULL; 637 lock( &this ->lock DEBUG_CTX2 );638 this ->count += 1;639 if ( this ->count <= 0 ) {637 lock( &this.lock DEBUG_CTX2 ); 638 this.count += 1; 639 if ( this.count <= 0 ) { 640 640 // remove task at head of waiting list 641 thrd = pop_head( &this ->waiting );642 } 643 644 unlock( &this ->lock );641 thrd = pop_head( &this.waiting ); 642 } 643 644 unlock( &this.lock ); 645 645 646 646 // make new owner -
src/libcfa/concurrency/monitor
re1e8408 r4cedd9f 116 116 } 117 117 118 void wait( condition *this, uintptr_t user_info = 0 );119 bool signal( condition *this );120 bool signal_block( condition *this );121 static inline bool is_empty( condition * this ) { return !this->blocked.head; }122 uintptr_t front( condition *this );118 void wait( condition & this, uintptr_t user_info = 0 ); 119 bool signal( condition & this ); 120 bool signal_block( condition & this ); 121 static inline bool is_empty( condition & this ) { return !this.blocked.head; } 122 uintptr_t front( condition & this ); 123 123 124 124 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor.c
re1e8408 r4cedd9f 45 45 46 46 static inline thread_desc * check_condition ( __condition_criterion_t * ); 47 static inline void brand_condition ( condition *);47 static inline void brand_condition ( condition & ); 48 48 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count ); 49 49 … … 69 69 unsigned short count = cnt; /* Save the count to a local variable */ \ 70 70 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 71 __waitfor_mask_t masks [ count ];/* Save the current waitfor masks to restore them later */ \71 __waitfor_mask_t masks [ count ]; /* Save the current waitfor masks to restore them later */ \ 72 72 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 73 73 … … 387 387 //----------------------------------------------------------------------------- 388 388 // Internal scheduling 389 void wait( condition *this, uintptr_t user_info = 0 ) {389 void wait( condition & this, uintptr_t user_info = 0 ) { 390 390 brand_condition( this ); 391 391 392 392 // Check that everything is as expected 393 assertf( this ->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );394 verifyf( this ->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );395 verifyf( this ->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );393 assertf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors ); 394 verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%i)", this.monitor_count ); 395 verifyf( this.monitor_count < 32u, "Excessive monitor count (%i)", this.monitor_count ); 396 396 397 397 // Create storage for monitor context 398 monitor_ctx( this ->monitors, this->monitor_count );398 monitor_ctx( this.monitors, this.monitor_count ); 399 399 400 400 // Create the node specific to this wait operation … … 403 403 // Append the current wait operation to the ones already queued on the condition 404 404 // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion 405 append( &this ->blocked, &waiter );405 append( &this.blocked, &waiter ); 406 406 407 407 // Lock all monitors (aggregates the locks as well) … … 429 429 } 430 430 431 bool signal( condition *this ) {431 bool signal( condition & this ) { 432 432 if( is_empty( this ) ) { return false; } 433 433 434 434 //Check that everything is as expected 435 verify( this ->monitors );436 verify( this ->monitor_count != 0 );435 verify( this.monitors ); 436 verify( this.monitor_count != 0 ); 437 437 438 438 //Some more checking in debug 439 439 LIB_DEBUG_DO( 440 440 thread_desc * this_thrd = this_thread; 441 if ( this ->monitor_count != this_thrd->monitors.size ) {442 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );443 } 444 445 for(int i = 0; i < this ->monitor_count; i++) {446 if ( this ->monitors[i] != this_thrd->monitors.list[i] ) {447 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );441 if ( this.monitor_count != this_thrd->monitors.size ) { 442 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size ); 443 } 444 445 for(int i = 0; i < this.monitor_count; i++) { 446 if ( this.monitors[i] != this_thrd->monitors.list[i] ) { 447 abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors.list[i] ); 448 448 } 449 449 } 450 450 ); 451 451 452 unsigned short count = this ->monitor_count;452 unsigned short count = this.monitor_count; 453 453 454 454 // Lock all monitors 455 lock_all( this ->monitors, NULL, count );455 lock_all( this.monitors, NULL, count ); 456 456 457 457 //Pop the head of the waiting queue 458 __condition_node_t * node = pop_head( &this ->blocked );458 __condition_node_t * node = pop_head( &this.blocked ); 459 459 460 460 //Add the thread to the proper AS stack … … 466 466 467 467 //Release 468 unlock_all( this ->monitors, count );468 unlock_all( this.monitors, count ); 469 469 470 470 return true; 471 471 } 472 472 473 bool signal_block( condition *this ) {474 if( !this ->blocked.head ) { return false; }473 bool signal_block( condition & this ) { 474 if( !this.blocked.head ) { return false; } 475 475 476 476 //Check that everything is as expected 477 verifyf( this ->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );478 verifyf( this ->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );477 verifyf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors ); 478 verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%i)", this.monitor_count ); 479 479 480 480 // Create storage for monitor context 481 monitor_ctx( this ->monitors, this->monitor_count );481 monitor_ctx( this.monitors, this.monitor_count ); 482 482 483 483 // Lock all monitors (aggregates the locks them as well) … … 491 491 492 492 //Find the thread to run 493 thread_desc * signallee = pop_head( &this ->blocked )->waiting_thread;493 thread_desc * signallee = pop_head( &this.blocked )->waiting_thread; 494 494 set_owner( monitors, count, signallee ); 495 495 496 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );496 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee ); 497 497 498 498 //Everything is ready to go to sleep … … 512 512 513 513 // Access the user_info of the thread waiting at the front of the queue 514 uintptr_t front( condition *this ) {514 uintptr_t front( condition & this ) { 515 515 verifyf( !is_empty(this), 516 516 "Attempt to access user data on an empty condition.\n" 517 517 "Possible cause is not checking if the condition is empty before reading stored data." 518 518 ); 519 return this ->blocked.head->user_info;519 return this.blocked.head->user_info; 520 520 } 521 521 … … 811 811 } 812 812 813 static inline void brand_condition( condition *this ) {813 static inline void brand_condition( condition & this ) { 814 814 thread_desc * thrd = this_thread; 815 if( !this ->monitors ) {815 if( !this.monitors ) { 816 816 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 817 817 assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list ); 818 this ->monitor_count = thrd->monitors.size;819 820 this ->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );821 for( int i = 0; i < this ->monitor_count; i++ ) {822 this ->monitors[i] = thrd->monitors.list[i];818 this.monitor_count = thrd->monitors.size; 819 820 this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) ); 821 for( int i = 0; i < this.monitor_count; i++ ) { 822 this.monitors[i] = thrd->monitors.list[i]; 823 823 } 824 824 }
Note: See TracChangeset
for help on using the changeset viewer.