Changes in / [6d2386e:3edc2df]
- Location:
- src/libcfa
- Files:
-
- 3 deleted
- 9 edited
-
Makefile.am (modified) (1 diff)
-
Makefile.in (modified) (2 diffs)
-
bits/containers.h (deleted)
-
bits/defs.h (deleted)
-
bits/locks.h (deleted)
-
concurrency/alarm.c (modified) (3 diffs)
-
concurrency/invoke.h (modified) (4 diffs)
-
concurrency/kernel (modified) (3 diffs)
-
concurrency/kernel.c (modified) (17 diffs)
-
concurrency/kernel_private.h (modified) (2 diffs)
-
concurrency/monitor.c (modified) (14 diffs)
-
concurrency/preemption.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/Makefile.am
r6d2386e r3edc2df 95 95 96 96 cfa_includedir = $(CFA_INCDIR) 97 nobase_cfa_include_HEADERS = \ 98 ${headers} \ 99 ${stdhdr} \ 100 math \ 101 gmp \ 102 bits/defs.h \ 103 bits/locks.h \ 104 concurrency/invoke.h \ 105 libhdr.h \ 106 libhdr/libalign.h \ 107 libhdr/libdebug.h \ 108 libhdr/libtools.h 97 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 109 98 110 99 CLEANFILES = libcfa-prelude.c -
src/libcfa/Makefile.in
r6d2386e r3edc2df 264 264 containers/result containers/vector concurrency/coroutine \ 265 265 concurrency/thread concurrency/kernel concurrency/monitor \ 266 ${shell echo stdhdr/*} math gmp bits/defs.h bits/locks.h \ 267 concurrency/invoke.h libhdr.h libhdr/libalign.h \ 268 libhdr/libdebug.h libhdr/libtools.h 266 ${shell echo stdhdr/*} math gmp concurrency/invoke.h 269 267 HEADERS = $(nobase_cfa_include_HEADERS) 270 268 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 432 430 stdhdr = ${shell echo stdhdr/*} 433 431 cfa_includedir = $(CFA_INCDIR) 434 nobase_cfa_include_HEADERS = \ 435 ${headers} \ 436 ${stdhdr} \ 437 math \ 438 gmp \ 439 bits/defs.h \ 440 bits/locks.h \ 441 concurrency/invoke.h \ 442 libhdr.h \ 443 libhdr/libalign.h \ 444 libhdr/libdebug.h \ 445 libhdr/libtools.h 446 432 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 447 433 CLEANFILES = libcfa-prelude.c 448 434 all: all-am -
src/libcfa/concurrency/alarm.c
r6d2386e r3edc2df 186 186 187 187 disable_interrupts(); 188 lock( event_kernel->lock DEBUG_CTX2 );188 lock( &event_kernel->lock DEBUG_CTX2 ); 189 189 { 190 190 verify( validate( alarms ) ); … … 196 196 } 197 197 } 198 unlock( event_kernel->lock );198 unlock( &event_kernel->lock ); 199 199 this->set = true; 200 200 enable_interrupts( DEBUG_CTX ); … … 203 203 void unregister_self( alarm_node_t * this ) { 204 204 disable_interrupts(); 205 lock( event_kernel->lock DEBUG_CTX2 );205 lock( &event_kernel->lock DEBUG_CTX2 ); 206 206 { 207 207 verify( validate( &event_kernel->alarms ) ); 208 208 remove( &event_kernel->alarms, this ); 209 209 } 210 unlock( event_kernel->lock );210 unlock( &event_kernel->lock ); 211 211 enable_interrupts( DEBUG_CTX ); 212 212 this->set = false; -
src/libcfa/concurrency/invoke.h
r6d2386e r3edc2df 14 14 // 15 15 16 #include "bits/defs.h"17 #include "bits/locks.h"16 #include <stdbool.h> 17 #include <stdint.h> 18 18 19 19 #ifdef __CFORALL__ … … 25 25 #define _INVOKE_H_ 26 26 27 #define unlikely(x) __builtin_expect(!!(x), 0) 28 #define thread_local _Thread_local 29 27 30 typedef void (*fptr_t)(); 28 31 typedef int_fast16_t __lock_size_t; 32 33 struct spinlock { 34 volatile int lock; 35 #ifdef __CFA_DEBUG__ 36 const char * prev_name; 37 void* prev_thrd; 38 #endif 39 }; 29 40 30 41 struct __thread_queue_t { … … 47 58 void push( struct __condition_stack_t &, struct __condition_criterion_t * ); 48 59 struct __condition_criterion_t * pop( struct __condition_stack_t & ); 60 61 void ?{}(spinlock & this); 62 void ^?{}(spinlock & this); 49 63 } 50 64 #endif … … 108 122 struct monitor_desc { 109 123 // spinlock to protect internal data 110 struct __spinlock_tlock;124 struct spinlock lock; 111 125 112 126 // current owner of the monitor -
src/libcfa/concurrency/kernel
r6d2386e r3edc2df 26 26 //----------------------------------------------------------------------------- 27 27 // Locks 28 // //Lock the spinlock, spin if already acquired29 //void lock ( spinlock * DEBUG_CTX_PARAM2 );28 // Lock the spinlock, spin if already acquired 29 void lock ( spinlock * DEBUG_CTX_PARAM2 ); 30 30 31 // //Lock the spinlock, yield repeatedly if already acquired32 //void lock_yield( spinlock * DEBUG_CTX_PARAM2 );31 // Lock the spinlock, yield repeatedly if already acquired 32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 33 34 // //Lock the spinlock, return false if already acquired35 //bool try_lock ( spinlock * DEBUG_CTX_PARAM2 );34 // Lock the spinlock, return false if already acquired 35 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 36 36 37 // //Unlock the spinlock38 //void unlock ( spinlock * );37 // Unlock the spinlock 38 void unlock ( spinlock * ); 39 39 40 40 struct semaphore { 41 __spinlock_tlock;41 spinlock lock; 42 42 int count; 43 43 __thread_queue_t waiting; … … 54 54 struct cluster { 55 55 // Ready queue locks 56 __spinlock_tready_queue_lock;56 spinlock ready_queue_lock; 57 57 58 58 // Ready queue for threads … … 74 74 FinishOpCode action_code; 75 75 thread_desc * thrd; 76 __spinlock_t* lock;77 __spinlock_t** locks;76 spinlock * lock; 77 spinlock ** locks; 78 78 unsigned short lock_count; 79 79 thread_desc ** thrds; -
src/libcfa/concurrency/kernel.c
r6d2386e r3edc2df 242 242 void finishRunning(processor * this) { 243 243 if( this->finish.action_code == Release ) { 244 unlock( *this->finish.lock );244 unlock( this->finish.lock ); 245 245 } 246 246 else if( this->finish.action_code == Schedule ) { … … 248 248 } 249 249 else if( this->finish.action_code == Release_Schedule ) { 250 unlock( *this->finish.lock );250 unlock( this->finish.lock ); 251 251 ScheduleThread( this->finish.thrd ); 252 252 } 253 253 else if( this->finish.action_code == Release_Multi ) { 254 254 for(int i = 0; i < this->finish.lock_count; i++) { 255 unlock( *this->finish.locks[i] );255 unlock( this->finish.locks[i] ); 256 256 } 257 257 } 258 258 else if( this->finish.action_code == Release_Multi_Schedule ) { 259 259 for(int i = 0; i < this->finish.lock_count; i++) { 260 unlock( *this->finish.locks[i] );260 unlock( this->finish.locks[i] ); 261 261 } 262 262 for(int i = 0; i < this->finish.thrd_count; i++) { … … 334 334 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 335 335 336 lock( this_processor->cltr->ready_queue_lock DEBUG_CTX2 );336 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 ); 337 337 append( this_processor->cltr->ready_queue, thrd ); 338 unlock( this_processor->cltr->ready_queue_lock );338 unlock( &this_processor->cltr->ready_queue_lock ); 339 339 340 340 verify( disable_preempt_count > 0 ); … … 343 343 thread_desc * nextThread(cluster * this) { 344 344 verify( disable_preempt_count > 0 ); 345 lock( this->ready_queue_lock DEBUG_CTX2 );345 lock( &this->ready_queue_lock DEBUG_CTX2 ); 346 346 thread_desc * head = pop_head( this->ready_queue ); 347 unlock( this->ready_queue_lock );347 unlock( &this->ready_queue_lock ); 348 348 verify( disable_preempt_count > 0 ); 349 349 return head; … … 358 358 } 359 359 360 void BlockInternal( __spinlock_t* lock ) {360 void BlockInternal( spinlock * lock ) { 361 361 disable_interrupts(); 362 362 this_processor->finish.action_code = Release; … … 384 384 } 385 385 386 void BlockInternal( __spinlock_t* lock, thread_desc * thrd ) {386 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 387 387 assert(thrd); 388 388 disable_interrupts(); … … 398 398 } 399 399 400 void BlockInternal( __spinlock_t* locks [], unsigned short count) {400 void BlockInternal(spinlock * locks [], unsigned short count) { 401 401 disable_interrupts(); 402 402 this_processor->finish.action_code = Release_Multi; … … 411 411 } 412 412 413 void BlockInternal( __spinlock_t* locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {413 void BlockInternal(spinlock * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 414 414 disable_interrupts(); 415 415 this_processor->finish.action_code = Release_Multi_Schedule; … … 426 426 } 427 427 428 void LeaveThread( __spinlock_t* lock, thread_desc * thrd) {428 void LeaveThread(spinlock * lock, thread_desc * thrd) { 429 429 verify( disable_preempt_count > 0 ); 430 430 this_processor->finish.action_code = thrd ? Release_Schedule : Release; … … 516 516 } 517 517 518 static __spinlock_tkernel_abort_lock;519 static __spinlock_tkernel_debug_lock;518 static spinlock kernel_abort_lock; 519 static spinlock kernel_debug_lock; 520 520 static bool kernel_abort_called = false; 521 521 … … 523 523 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 524 524 // the globalAbort flag is true. 525 lock( kernel_abort_lock DEBUG_CTX2 );525 lock( &kernel_abort_lock DEBUG_CTX2 ); 526 526 527 527 // first task to abort ? 528 528 if ( !kernel_abort_called ) { // not first task to abort ? 529 529 kernel_abort_called = true; 530 unlock( kernel_abort_lock );530 unlock( &kernel_abort_lock ); 531 531 } 532 532 else { 533 unlock( kernel_abort_lock );533 unlock( &kernel_abort_lock ); 534 534 535 535 sigset_t mask; … … 561 561 extern "C" { 562 562 void __lib_debug_acquire() { 563 lock( kernel_debug_lock DEBUG_CTX2 );563 lock( &kernel_debug_lock DEBUG_CTX2 ); 564 564 } 565 565 566 566 void __lib_debug_release() { 567 unlock( kernel_debug_lock );567 unlock( &kernel_debug_lock ); 568 568 } 569 569 } … … 574 574 //----------------------------------------------------------------------------- 575 575 // Locks 576 void ?{}( spinlock & this ) { 577 this.lock = 0; 578 } 579 void ^?{}( spinlock & this ) { 580 581 } 582 583 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) { 584 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0; 585 } 586 587 void lock( spinlock * this DEBUG_CTX_PARAM2 ) { 588 for ( unsigned int i = 1;; i += 1 ) { 589 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 590 } 591 LIB_DEBUG_DO( 592 this->prev_name = caller; 593 this->prev_thrd = this_thread; 594 ) 595 } 596 597 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) { 598 for ( unsigned int i = 1;; i += 1 ) { 599 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 600 yield(); 601 } 602 LIB_DEBUG_DO( 603 this->prev_name = caller; 604 this->prev_thrd = this_thread; 605 ) 606 } 607 608 609 void unlock( spinlock * this ) { 610 __sync_lock_release_4( &this->lock ); 611 } 612 576 613 void ?{}( semaphore & this, int count = 1 ) { 577 614 (this.lock){}; … … 582 619 583 620 void P(semaphore & this) { 584 lock( this.lock DEBUG_CTX2 );621 lock( &this.lock DEBUG_CTX2 ); 585 622 this.count -= 1; 586 623 if ( this.count < 0 ) { … … 592 629 } 593 630 else { 594 unlock( this.lock );631 unlock( &this.lock ); 595 632 } 596 633 } … … 598 635 void V(semaphore & this) { 599 636 thread_desc * thrd = NULL; 600 lock( this.lock DEBUG_CTX2 );637 lock( &this.lock DEBUG_CTX2 ); 601 638 this.count += 1; 602 639 if ( this.count <= 0 ) { … … 605 642 } 606 643 607 unlock( this.lock );644 unlock( &this.lock ); 608 645 609 646 // make new owner -
src/libcfa/concurrency/kernel_private.h
r6d2386e r3edc2df 45 45 //Block current thread and release/wake-up the following resources 46 46 void BlockInternal(void); 47 void BlockInternal( __spinlock_t* lock);47 void BlockInternal(spinlock * lock); 48 48 void BlockInternal(thread_desc * thrd); 49 void BlockInternal( __spinlock_t* lock, thread_desc * thrd);50 void BlockInternal( __spinlock_t* locks [], unsigned short count);51 void BlockInternal( __spinlock_t* locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);52 void LeaveThread( __spinlock_t* lock, thread_desc * thrd);49 void BlockInternal(spinlock * lock, thread_desc * thrd); 50 void BlockInternal(spinlock * locks [], unsigned short count); 51 void BlockInternal(spinlock * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count); 52 void LeaveThread(spinlock * lock, thread_desc * thrd); 53 53 54 54 //----------------------------------------------------------------------------- … … 66 66 struct event_kernel_t { 67 67 alarm_list_t alarms; 68 __spinlock_tlock;68 spinlock lock; 69 69 }; 70 70 -
src/libcfa/concurrency/monitor.c
r6d2386e r3edc2df 34 34 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors ); 35 35 36 static inline void lock_all ( __spinlock_t* locks [], __lock_size_t count );37 static inline void lock_all ( monitor_desc * source [], __spinlock_t* /*out*/ locks [], __lock_size_t count );38 static inline void unlock_all( __spinlock_t* locks [], __lock_size_t count );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 39 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ); 40 40 41 static inline void save ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t* locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t* locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );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 43 44 44 static inline void init ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ); … … 53 53 static inline __lock_size_t count_max ( const __waitfor_mask_t & mask ); 54 54 static inline __lock_size_t aggregate ( monitor_desc * storage [], const __waitfor_mask_t & mask ); 55 56 #ifndef __CFA_LOCK_NO_YIELD57 #define DO_LOCK lock_yield58 #else59 #define DO_LOCK lock60 #endif61 55 62 56 //----------------------------------------------------------------------------- … … 77 71 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 78 72 __waitfor_mask_t masks [ count ]; /* Save the current waitfor masks to restore them later */ \ 79 __spinlock_t * locks[ count ]; /* We need to pass-in an array of locks to BlockInternal */ \73 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 80 74 81 75 #define monitor_save save ( monitors, count, locks, recursions, masks ) … … 90 84 // Enter single monitor 91 85 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) { 92 // Lock the monitor spinlock 93 DO_LOCK(this->lock DEBUG_CTX2 );86 // Lock the monitor spinlock, lock_yield to reduce contention 87 lock_yield( &this->lock DEBUG_CTX2 ); 94 88 thread_desc * thrd = this_thread; 95 89 … … 133 127 134 128 // Release the lock and leave 135 unlock( this->lock );129 unlock( &this->lock ); 136 130 return; 137 131 } 138 132 139 133 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 140 // Lock the monitor spinlock 141 DO_LOCK(this->lock DEBUG_CTX2 );134 // Lock the monitor spinlock, lock_yield to reduce contention 135 lock_yield( &this->lock DEBUG_CTX2 ); 142 136 thread_desc * thrd = this_thread; 143 137 … … 151 145 set_owner( this, thrd ); 152 146 153 unlock( this->lock );147 unlock( &this->lock ); 154 148 return; 155 149 } … … 202 196 // Leave single monitor 203 197 void __leave_monitor_desc( monitor_desc * this ) { 204 // Lock the monitor spinlock, DO_LOCKto reduce contention205 DO_LOCK(this->lock DEBUG_CTX2 );198 // Lock the monitor spinlock, lock_yield to reduce contention 199 lock_yield( &this->lock DEBUG_CTX2 ); 206 200 207 201 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); … … 216 210 if( this->recursion != 0) { 217 211 LIB_DEBUG_PRINT_SAFE("Kernel : recursion still %d\n", this->recursion); 218 unlock( this->lock );212 unlock( &this->lock ); 219 213 return; 220 214 } … … 224 218 225 219 // We can now let other threads in safely 226 unlock( this->lock );220 unlock( &this->lock ); 227 221 228 222 //We need to wake-up the thread … … 249 243 250 244 // Lock the monitor now 251 DO_LOCK(this->lock DEBUG_CTX2 );245 lock_yield( &this->lock DEBUG_CTX2 ); 252 246 253 247 disable_interrupts(); … … 736 730 } 737 731 738 static inline void lock_all( __spinlock_t* locks [], __lock_size_t count ) {732 static inline void lock_all( spinlock * locks [], __lock_size_t count ) { 739 733 for( __lock_size_t i = 0; i < count; i++ ) { 740 DO_LOCK( *locks[i] DEBUG_CTX2 );741 } 742 } 743 744 static inline void lock_all( monitor_desc * source [], __spinlock_t* /*out*/ locks [], __lock_size_t count ) {734 lock_yield( locks[i] DEBUG_CTX2 ); 735 } 736 } 737 738 static inline void lock_all( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count ) { 745 739 for( __lock_size_t i = 0; i < count; i++ ) { 746 __spinlock_t* l = &source[i]->lock;747 DO_LOCK( *l DEBUG_CTX2 );740 spinlock * l = &source[i]->lock; 741 lock_yield( l DEBUG_CTX2 ); 748 742 if(locks) locks[i] = l; 749 743 } 750 744 } 751 745 752 static inline void unlock_all( __spinlock_t* locks [], __lock_size_t count ) {746 static inline void unlock_all( spinlock * locks [], __lock_size_t count ) { 753 747 for( __lock_size_t i = 0; i < count; i++ ) { 754 unlock( *locks[i] );748 unlock( locks[i] ); 755 749 } 756 750 } … … 758 752 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) { 759 753 for( __lock_size_t i = 0; i < count; i++ ) { 760 unlock( locks[i]->lock );754 unlock( &locks[i]->lock ); 761 755 } 762 756 } … … 765 759 monitor_desc * ctx [], 766 760 __lock_size_t count, 767 __attribute((unused)) __spinlock_t* locks [],761 __attribute((unused)) spinlock * locks [], 768 762 unsigned int /*out*/ recursions [], 769 763 __waitfor_mask_t /*out*/ masks [] … … 778 772 monitor_desc * ctx [], 779 773 __lock_size_t count, 780 __spinlock_t* locks [],774 spinlock * locks [], 781 775 unsigned int /*out*/ recursions [], 782 776 __waitfor_mask_t /*out*/ masks [] -
src/libcfa/concurrency/preemption.c
r6d2386e r3edc2df 355 355 case SI_KERNEL: 356 356 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 357 lock( event_kernel->lock DEBUG_CTX2 );357 lock( &event_kernel->lock DEBUG_CTX2 ); 358 358 tick_preemption(); 359 unlock( event_kernel->lock );359 unlock( &event_kernel->lock ); 360 360 break; 361 361 // Signal was not sent by the kernel but by an other thread
Note:
See TracChangeset
for help on using the changeset viewer.