- File:
-
- 1 edited
-
src/libcfa/concurrency/monitor.c (modified) (40 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
r2f6a7e93 rde737c8 17 17 18 18 #include <stdlib> 19 #include <inttypes.h>20 19 21 20 #include "libhdr.h" … … 27 26 // Forward declarations 28 27 static inline void set_owner ( monitor_desc * this, thread_desc * owner ); 29 static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );30 static inline void set_mask ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask );28 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner ); 29 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 31 30 static inline void reset_mask( monitor_desc * this ); 32 31 … … 34 33 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors ); 35 34 36 static inline void lock_all ( spinlock * locks [], __lock_size_t count );37 static inline void lock_all ( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count );38 static inline void unlock_all( spinlock * locks [], __lock_size_t count );39 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );40 41 static inline void save ( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks []);42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks []);43 44 static inline void init ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria []);45 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria []);35 static inline void lock_all( spinlock ** locks, unsigned short count ); 36 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ); 37 static inline void unlock_all( spinlock ** locks, unsigned short count ); 38 static inline void unlock_all( monitor_desc ** locks, unsigned short count ); 39 40 static inline void save ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ); 41 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks ); 42 43 static inline void init ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 44 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 46 45 47 46 static inline thread_desc * check_condition ( __condition_criterion_t * ); 48 static inline void brand_condition ( condition &);49 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );47 static inline void brand_condition ( condition * ); 48 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count ); 50 49 51 50 forall(dtype T | sized( T )) 52 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );53 static inline __lock_size_t count_max ( const __waitfor_mask_t & mask );54 static inline __lock_size_t aggregate ( monitor_desc * storage [], const __waitfor_mask_t & mask );51 static inline short insert_unique( T ** array, short & size, T * val ); 52 static inline short count_max ( const __waitfor_mask_t & mask ); 53 static inline short aggregate ( monitor_desc ** storage, const __waitfor_mask_t & mask ); 55 54 56 55 //----------------------------------------------------------------------------- … … 59 58 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 60 59 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 61 init( count, monitors, waiter, criteria );/* Link everything together */ \60 init( count, monitors, &waiter, criteria ); /* Link everything together */ \ 62 61 63 62 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 64 63 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 65 64 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 66 init_push( count, monitors, waiter, criteria );/* Link everything together and push it to the AS-Stack */ \65 init_push( count, monitors, &waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \ 67 66 68 67 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \ 69 68 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \ 70 __lock_size_t count = cnt;/* Save the count to a local variable */ \69 unsigned short count = cnt; /* Save the count to a local variable */ \ 71 70 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 72 __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 */ \ 73 72 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 74 73 … … 115 114 116 115 // Some one else has the monitor, wait in line for it 117 append( this->entry_queue, thrd );116 append( &this->entry_queue, thrd ); 118 117 BlockInternal( &this->lock ); 119 118 … … 154 153 } 155 154 156 __lock_size_t count = 1;155 int count = 1; 157 156 monitor_desc ** monitors = &this; 158 157 __monitor_group_t group = { &this, 1, func }; … … 161 160 162 161 // Wake the thread that is waiting for this 163 __condition_criterion_t * urgent = pop( this->signal_stack );162 __condition_criterion_t * urgent = pop( &this->signal_stack ); 164 163 verify( urgent ); 165 164 … … 183 182 184 183 // Some one else has the monitor, wait in line for it 185 append( this->entry_queue, thrd );184 append( &this->entry_queue, thrd ); 186 185 BlockInternal( &this->lock ); 187 186 … … 273 272 // relies on the monitor array being sorted 274 273 static inline void enter( __monitor_group_t monitors ) { 275 for( __lock_size_t i = 0; i < monitors.size; i++) {274 for(int i = 0; i < monitors.size; i++) { 276 275 __enter_monitor_desc( monitors.list[i], monitors ); 277 276 } … … 280 279 // Leave multiple monitor 281 280 // relies on the monitor array being sorted 282 static inline void leave(monitor_desc * monitors [], __lock_size_t count) {283 for( __lock_size_t i = count - 1; i >= 0; i--) {281 static inline void leave(monitor_desc ** monitors, int count) { 282 for(int i = count - 1; i >= 0; i--) { 284 283 __leave_monitor_desc( monitors[i] ); 285 284 } … … 288 287 // Ctor for monitor guard 289 288 // Sorts monitors before entering 290 void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {289 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) { 291 290 // Store current array 292 291 this.m = m; … … 297 296 298 297 // Save previous thread context 299 this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func]; 298 this.prev_mntrs = this_thread->monitors.list; 299 this.prev_count = this_thread->monitors.size; 300 this.prev_func = this_thread->monitors.func; 300 301 301 302 // Update thread context (needed for conditions) 302 this_thread->monitors.[list, size, func] = [m, count, func]; 303 this_thread->monitors.list = m; 304 this_thread->monitors.size = count; 305 this_thread->monitors.func = func; 303 306 304 307 // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count); … … 322 325 323 326 // Restore thread context 324 this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func]; 325 } 327 this_thread->monitors.list = this.prev_mntrs; 328 this_thread->monitors.size = this.prev_count; 329 this_thread->monitors.func = this.prev_func; 330 } 331 326 332 327 333 // Ctor for monitor guard 328 334 // Sorts monitors before entering 329 void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {335 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) { 330 336 // Store current array 331 337 this.m = *m; 332 338 333 339 // Save previous thread context 334 this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func]; 340 this.prev_mntrs = this_thread->monitors.list; 341 this.prev_count = this_thread->monitors.size; 342 this.prev_func = this_thread->monitors.func; 335 343 336 344 // Update thread context (needed for conditions) 337 this_thread->monitors.[list, size, func] = [m, 1, func]; 345 this_thread->monitors.list = m; 346 this_thread->monitors.size = 1; 347 this_thread->monitors.func = func; 338 348 339 349 __enter_monitor_dtor( this.m, func ); 340 350 } 351 341 352 342 353 // Dtor for monitor guard … … 346 357 347 358 // Restore thread context 348 this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func]; 359 this_thread->monitors.list = this.prev_mntrs; 360 this_thread->monitors.size = this.prev_count; 361 this_thread->monitors.func = this.prev_func; 349 362 } 350 363 351 364 //----------------------------------------------------------------------------- 352 365 // Internal scheduling types 353 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {366 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) { 354 367 this.waiting_thread = waiting_thread; 355 368 this.count = count; … … 365 378 } 366 379 367 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t &owner ) {380 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ) { 368 381 this.ready = false; 369 382 this.target = target; 370 this.owner = &owner;383 this.owner = owner; 371 384 this.next = NULL; 372 385 } … … 374 387 //----------------------------------------------------------------------------- 375 388 // Internal scheduling 376 void wait( condition &this, uintptr_t user_info = 0 ) {389 void wait( condition * this, uintptr_t user_info = 0 ) { 377 390 brand_condition( this ); 378 391 379 392 // Check that everything is as expected 380 assertf( this .monitors != NULL, "Waiting with no monitors (%p)", this.monitors );381 verifyf( this .monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );382 verifyf( this .monitor_count < 32u, "Excessive monitor count (%"PRIiFAST16")", 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 ); 383 396 384 397 // Create storage for monitor context 385 monitor_ctx( this .monitors, this.monitor_count );398 monitor_ctx( this->monitors, this->monitor_count ); 386 399 387 400 // Create the node specific to this wait operation … … 390 403 // Append the current wait operation to the ones already queued on the condition 391 404 // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion 392 append( this.blocked, &waiter );405 append( &this->blocked, &waiter ); 393 406 394 407 // Lock all monitors (aggregates the locks as well) … … 396 409 397 410 // Find the next thread(s) to run 398 __lock_size_t thread_count = 0;411 short thread_count = 0; 399 412 thread_desc * threads[ count ]; 400 413 __builtin_memset( threads, 0, sizeof( threads ) ); … … 404 417 405 418 // Remove any duplicate threads 406 for( __lock_size_t i = 0; i < count; i++) {419 for( int i = 0; i < count; i++) { 407 420 thread_desc * new_owner = next_thread( monitors[i] ); 408 421 insert_unique( threads, thread_count, new_owner ); … … 416 429 } 417 430 418 bool signal( condition &this ) {431 bool signal( condition * this ) { 419 432 if( is_empty( this ) ) { return false; } 420 433 421 434 //Check that everything is as expected 422 verify( this .monitors );423 verify( this .monitor_count != 0 );435 verify( this->monitors ); 436 verify( this->monitor_count != 0 ); 424 437 425 438 //Some more checking in debug 426 439 LIB_DEBUG_DO( 427 440 thread_desc * this_thrd = this_thread; 428 if ( this .monitor_count != this_thrd->monitors.size ) {429 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size );430 } 431 432 for(int i = 0; i < this .monitor_count; i++) {433 if ( this .monitors[i] != this_thrd->monitors.list[i] ) {434 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] ); 435 448 } 436 449 } 437 450 ); 438 451 439 __lock_size_t count = this.monitor_count;452 unsigned short count = this->monitor_count; 440 453 441 454 // Lock all monitors 442 lock_all( this .monitors, NULL, count );455 lock_all( this->monitors, NULL, count ); 443 456 444 457 //Pop the head of the waiting queue 445 __condition_node_t * node = pop_head( this.blocked );458 __condition_node_t * node = pop_head( &this->blocked ); 446 459 447 460 //Add the thread to the proper AS stack … … 449 462 __condition_criterion_t * crit = &node->criteria[i]; 450 463 assert( !crit->ready ); 451 push( crit->target->signal_stack, crit );464 push( &crit->target->signal_stack, crit ); 452 465 } 453 466 454 467 //Release 455 unlock_all( this .monitors, count );468 unlock_all( this->monitors, count ); 456 469 457 470 return true; 458 471 } 459 472 460 bool signal_block( condition &this ) {461 if( !this .blocked.head ) { return false; }473 bool signal_block( condition * this ) { 474 if( !this->blocked.head ) { return false; } 462 475 463 476 //Check that everything is as expected 464 verifyf( this .monitors != NULL, "Waiting with no monitors (%p)", this.monitors );465 verifyf( this .monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", 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 ); 466 479 467 480 // Create storage for monitor context 468 monitor_ctx( this .monitors, this.monitor_count );481 monitor_ctx( this->monitors, this->monitor_count ); 469 482 470 483 // Lock all monitors (aggregates the locks them as well) … … 478 491 479 492 //Find the thread to run 480 thread_desc * signallee = pop_head( this.blocked )->waiting_thread;493 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread; 481 494 set_owner( monitors, count, signallee ); 482 495 483 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 ); 484 497 485 498 //Everything is ready to go to sleep … … 499 512 500 513 // Access the user_info of the thread waiting at the front of the queue 501 uintptr_t front( condition &this ) {514 uintptr_t front( condition * this ) { 502 515 verifyf( !is_empty(this), 503 516 "Attempt to access user data on an empty condition.\n" 504 517 "Possible cause is not checking if the condition is empty before reading stored data." 505 518 ); 506 return this .blocked.head->user_info;519 return this->blocked.head->user_info; 507 520 } 508 521 … … 524 537 // This statment doesn't have a contiguous list of monitors... 525 538 // Create one! 526 __lock_size_t max = count_max( mask );539 short max = count_max( mask ); 527 540 monitor_desc * mon_storage[max]; 528 541 __builtin_memset( mon_storage, 0, sizeof( mon_storage ) ); 529 __lock_size_t actual_count = aggregate( mon_storage, mask );530 531 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, ( __lock_size_t)max);542 short actual_count = aggregate( mon_storage, mask ); 543 544 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max); 532 545 533 546 if(actual_count == 0) return; … … 556 569 557 570 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria; 558 push( mon2dtor->signal_stack, dtor_crit );571 push( &mon2dtor->signal_stack, dtor_crit ); 559 572 560 573 unlock_all( locks, count ); … … 616 629 set_mask( monitors, count, mask ); 617 630 618 for( __lock_size_t i = 0; i < count; i++) {631 for(int i = 0; i < count; i++) { 619 632 verify( monitors[i]->owner == this_thread ); 620 633 } … … 648 661 } 649 662 650 static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {663 static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) { 651 664 monitors[0]->owner = owner; 652 665 monitors[0]->recursion = 1; 653 for( __lock_size_t i = 1; i < count; i++ ) {666 for( int i = 1; i < count; i++ ) { 654 667 monitors[i]->owner = owner; 655 668 monitors[i]->recursion = 0; … … 657 670 } 658 671 659 static inline void set_mask( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) {660 for( __lock_size_t i = 0; i < count; i++) {672 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) { 673 for(int i = 0; i < count; i++) { 661 674 storage[i]->mask = mask; 662 675 } … … 672 685 //Check the signaller stack 673 686 LIB_DEBUG_PRINT_SAFE("Kernel : mon %p AS-stack top %p\n", this, this->signal_stack.top); 674 __condition_criterion_t * urgent = pop( this->signal_stack );687 __condition_criterion_t * urgent = pop( &this->signal_stack ); 675 688 if( urgent ) { 676 689 //The signaller stack is not empty, … … 684 697 // No signaller thread 685 698 // Get the next thread in the entry_queue 686 thread_desc * new_owner = pop_head( this->entry_queue );699 thread_desc * new_owner = pop_head( &this->entry_queue ); 687 700 set_owner( this, new_owner ); 688 701 … … 692 705 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) { 693 706 __acceptable_t * it = this->mask.clauses; // Optim 694 __lock_size_t count = this->mask.size;707 int count = this->mask.size; 695 708 696 709 // Check if there are any acceptable functions … … 701 714 702 715 // For all acceptable functions check if this is the current function. 703 for( __lock_size_t i = 0; i < count; i++, it++ ) {716 for( short i = 0; i < count; i++, it++ ) { 704 717 if( *it == group ) { 705 718 *this->mask.accepted = i; … … 712 725 } 713 726 714 static inline void init( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria []) {715 for( __lock_size_t i = 0; i < count; i++) {727 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) { 728 for(int i = 0; i < count; i++) { 716 729 (criteria[i]){ monitors[i], waiter }; 717 730 } 718 731 719 waiter .criteria = criteria;720 } 721 722 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria []) {723 for( __lock_size_t i = 0; i < count; i++) {732 waiter->criteria = criteria; 733 } 734 735 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) { 736 for(int i = 0; i < count; i++) { 724 737 (criteria[i]){ monitors[i], waiter }; 725 738 LIB_DEBUG_PRINT_SAFE( "Kernel : target %p = %p\n", criteria[i].target, &criteria[i] ); 726 push( criteria[i].target->signal_stack, &criteria[i] );727 } 728 729 waiter .criteria = criteria;730 } 731 732 static inline void lock_all( spinlock * locks [], __lock_size_t count ) {733 for( __lock_size_t i = 0; i < count; i++ ) {739 push( &criteria[i].target->signal_stack, &criteria[i] ); 740 } 741 742 waiter->criteria = criteria; 743 } 744 745 static inline void lock_all( spinlock ** locks, unsigned short count ) { 746 for( int i = 0; i < count; i++ ) { 734 747 lock_yield( locks[i] DEBUG_CTX2 ); 735 748 } 736 749 } 737 750 738 static inline void lock_all( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count ) {739 for( __lock_size_t i = 0; i < count; i++ ) {751 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) { 752 for( int i = 0; i < count; i++ ) { 740 753 spinlock * l = &source[i]->lock; 741 754 lock_yield( l DEBUG_CTX2 ); … … 744 757 } 745 758 746 static inline void unlock_all( spinlock * locks [], __lock_size_t count ) {747 for( __lock_size_t i = 0; i < count; i++ ) {759 static inline void unlock_all( spinlock ** locks, unsigned short count ) { 760 for( int i = 0; i < count; i++ ) { 748 761 unlock( locks[i] ); 749 762 } 750 763 } 751 764 752 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) {753 for( __lock_size_t i = 0; i < count; i++ ) {765 static inline void unlock_all( monitor_desc ** locks, unsigned short count ) { 766 for( int i = 0; i < count; i++ ) { 754 767 unlock( &locks[i]->lock ); 755 768 } 756 769 } 757 770 758 static inline void save( 759 monitor_desc * ctx [], 760 __lock_size_t count, 761 __attribute((unused)) spinlock * locks [], 762 unsigned int /*out*/ recursions [], 763 __waitfor_mask_t /*out*/ masks [] 764 ) { 765 for( __lock_size_t i = 0; i < count; i++ ) { 771 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 772 for( int i = 0; i < count; i++ ) { 766 773 recursions[i] = ctx[i]->recursion; 767 774 masks[i] = ctx[i]->mask; … … 769 776 } 770 777 771 static inline void restore( 772 monitor_desc * ctx [], 773 __lock_size_t count, 774 spinlock * locks [], 775 unsigned int /*out*/ recursions [], 776 __waitfor_mask_t /*out*/ masks [] 777 ) { 778 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 778 779 lock_all( locks, count ); 779 for( __lock_size_t i = 0; i < count; i++ ) {780 for( int i = 0; i < count; i++ ) { 780 781 ctx[i]->recursion = recursions[i]; 781 782 ctx[i]->mask = masks[i]; … … 810 811 } 811 812 812 static inline void brand_condition( condition &this ) {813 static inline void brand_condition( condition * this ) { 813 814 thread_desc * thrd = this_thread; 814 if( !this .monitors ) {815 if( !this->monitors ) { 815 816 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 816 817 assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list ); 817 this .monitor_count = thrd->monitors.size;818 819 this .monitors = malloc( this.monitor_count * sizeof( *this.monitors ) );820 for( int i = 0; i < this .monitor_count; i++ ) {821 this .monitors[i] = thrd->monitors.list[i];822 } 823 } 824 } 825 826 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) {827 828 __thread_queue_t & entry_queue =monitors[0]->entry_queue;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 } 824 } 825 } 826 827 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) { 828 829 __thread_queue_t * entry_queue = &monitors[0]->entry_queue; 829 830 830 831 // For each thread in the entry-queue 831 for( thread_desc ** thrd_it = &entry_queue .head;832 for( thread_desc ** thrd_it = &entry_queue->head; 832 833 *thrd_it; 833 834 thrd_it = &(*thrd_it)->next … … 851 852 852 853 forall(dtype T | sized( T )) 853 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) {854 static inline short insert_unique( T ** array, short & size, T * val ) { 854 855 if( !val ) return size; 855 856 856 for( __lock_size_t i = 0; i <= size; i++) {857 for(int i = 0; i <= size; i++) { 857 858 if( array[i] == val ) return size; 858 859 } … … 863 864 } 864 865 865 static inline __lock_size_t count_max( const __waitfor_mask_t & mask ) {866 __lock_size_t max = 0;867 for( __lock_size_t i = 0; i < mask.size; i++ ) {866 static inline short count_max( const __waitfor_mask_t & mask ) { 867 short max = 0; 868 for( int i = 0; i < mask.size; i++ ) { 868 869 max += mask.clauses[i].size; 869 870 } … … 871 872 } 872 873 873 static inline __lock_size_t aggregate( monitor_desc * storage [], const __waitfor_mask_t & mask ) {874 __lock_size_t size = 0;875 for( __lock_size_t i = 0; i < mask.size; i++ ) {874 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) { 875 short size = 0; 876 for( int i = 0; i < mask.size; i++ ) { 876 877 __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size ); 877 for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {878 for( int j = 0; j < mask.clauses[i].size; j++) { 878 879 insert_unique( storage, size, mask.clauses[i].list[j] ); 879 880 } … … 889 890 } 890 891 891 void append( __condition_blocked_queue_t &this, __condition_node_t * c ) {892 verify(this .tail != NULL);893 *this .tail = c;894 this .tail = &c->next;895 } 896 897 __condition_node_t * pop_head( __condition_blocked_queue_t &this ) {898 __condition_node_t * head = this .head;892 void append( __condition_blocked_queue_t * this, __condition_node_t * c ) { 893 verify(this->tail != NULL); 894 *this->tail = c; 895 this->tail = &c->next; 896 } 897 898 __condition_node_t * pop_head( __condition_blocked_queue_t * this ) { 899 __condition_node_t * head = this->head; 899 900 if( head ) { 900 this .head = head->next;901 this->head = head->next; 901 902 if( !head->next ) { 902 this .tail = &this.head;903 this->tail = &this->head; 903 904 } 904 905 head->next = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.