Changeset 65deb18
- Timestamp:
- Jan 30, 2018, 3:52:42 PM (7 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:
- f792cb8
- Parents:
- 5b51f5e
- Location:
- src/libcfa
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/bits/containers.h
r5b51f5e r65deb18 140 140 141 141 #ifdef __cforall 142 142 143 forall(dtype T | is_node(T)) 143 static inline void ?{}( __queue(T) & this ) {144 (this.head){ NULL };145 (this.tail){ &this.head };144 static inline void ?{}( __queue(T) & this ) with( this ) { 145 head{ NULL }; 146 tail{ &head }; 146 147 } 147 148 148 149 forall(dtype T | is_node(T) | sized(T)) 149 static inline void append( __queue(T) & this, T * val ) {150 verify(t his.tail != NULL);151 *t his.tail = val;152 t his.tail = &get_next( *val );150 static inline void append( __queue(T) & this, T * val ) with( this ) { 151 verify(tail != NULL); 152 *tail = val; 153 tail = &get_next( *val ); 153 154 } 154 155 … … 167 168 168 169 forall(dtype T | is_node(T) | sized(T)) 169 static inline T * remove( __queue(T) & this, T ** it ) {170 static inline T * remove( __queue(T) & this, T ** it ) with( this ) { 170 171 T * val = *it; 171 172 verify( val ); … … 173 174 (*it) = get_next( *val ); 174 175 175 if( t his.tail == &get_next( *val ) ) {176 t his.tail = it;176 if( tail == &get_next( *val ) ) { 177 tail = it; 177 178 } 178 179 179 180 get_next( *val ) = NULL; 180 181 181 verify( ( this.head == NULL) == (&this.head == this.tail) );182 verify( *t his.tail == NULL );182 verify( (head == NULL) == (&head == tail) ); 183 verify( *tail == NULL ); 183 184 return val; 184 185 } 185 186 #endif 187 188 //----------------------------------------------------------------------------- 189 // Tools 190 //----------------------------------------------------------------------------- 191 #ifdef __cforall 192 193 #endif -
src/libcfa/concurrency/coroutine.c
r5b51f5e r65deb18 118 118 } //ctxSwitchDirect 119 119 120 void create_stack( coStack_t* this, unsigned int storageSize ) {120 void create_stack( coStack_t* this, unsigned int storageSize ) with( *this ) { 121 121 //TEMP HACK do this on proper kernel startup 122 122 if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE ); … … 124 124 size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment 125 125 126 if ( (intptr_t) this->storage == 0 ) {127 this->userStack = false;128 this->size = libCeiling( storageSize, 16 );126 if ( (intptr_t)storage == 0 ) { 127 userStack = false; 128 size = libCeiling( storageSize, 16 ); 129 129 // use malloc/memalign because "new" raises an exception for out-of-memory 130 130 131 131 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 132 __cfaabi_dbg_debug_do( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );133 __cfaabi_dbg_no_debug_do( this->storage = malloc( cxtSize + this->size + 8 ) );132 __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) ); 133 __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) ); 134 134 135 135 __cfaabi_dbg_debug_do( 136 if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) {136 if ( mprotect( storage, pageSize, PROT_NONE ) == -1 ) { 137 137 abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) ); 138 138 } // if 139 139 ); 140 140 141 if ( (intptr_t) this->storage == 0 ) {142 abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", this->size );141 if ( (intptr_t)storage == 0 ) { 142 abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", size ); 143 143 } // if 144 144 145 __cfaabi_dbg_debug_do( this->limit = (char *)this->storage + pageSize );146 __cfaabi_dbg_no_debug_do( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment145 __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize ); 146 __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment 147 147 148 148 } else { 149 assertf( ((size_t) this->storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", this->storage, (int)libAlign() );150 this->userStack = true;151 this->size = storageSize - cxtSize;149 assertf( ((size_t)storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", storage, (int)libAlign() ); 150 userStack = true; 151 size = storageSize - cxtSize; 152 152 153 if ( this->size % 16 != 0u ) this->size -= 8;153 if ( size % 16 != 0u ) size -= 8; 154 154 155 this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment155 limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment 156 156 } // if 157 assertf( this->size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", this->size, MinStackSize );157 assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize ); 158 158 159 this->base = (char *)this->limit + this->size;160 this->context = this->base;161 t his->top = (char *)this->context + cxtSize;159 base = (char *)limit + size; 160 context = base; 161 top = (char *)context + cxtSize; 162 162 } 163 163 -
src/libcfa/concurrency/kernel.c
r5b51f5e r65deb18 85 85 } 86 86 87 void ?{}( coStack_t & this, current_stack_info_t * info) {88 this.size= info->size;89 this.storage= info->storage;90 this.limit= info->limit;91 this.base= info->base;92 this.context= info->context;93 t his.top= info->top;94 this.userStack = true;95 } 96 97 void ?{}( coroutine_desc & this, current_stack_info_t * info) {98 (this.stack){ info };99 this.name = "Main Thread";100 this.errno_ = 0;101 this.state = Start;102 this.starter = NULL;103 } 104 105 void ?{}( thread_desc & this, current_stack_info_t * info) {106 (this.self_cor){ info };87 void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) { 88 size = info->size; 89 storage = info->storage; 90 limit = info->limit; 91 base = info->base; 92 context = info->context; 93 top = info->top; 94 userStack = true; 95 } 96 97 void ?{}( coroutine_desc & this, current_stack_info_t * info) with( this ) { 98 stack{ info }; 99 name = "Main Thread"; 100 errno_ = 0; 101 state = Start; 102 starter = NULL; 103 } 104 105 void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) { 106 self_cor{ info }; 107 107 } 108 108 … … 131 131 void ?{}(processor & this, cluster * cltr) { 132 132 this.cltr = cltr; 133 (this.terminated){ 0 };133 this.terminated{ 0 }; 134 134 this.do_terminate = false; 135 135 this.preemption_alarm = NULL; … … 141 141 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) { 142 142 this.cltr = cltr; 143 (this.terminated){ 0 };143 this.terminated{ 0 }; 144 144 this.do_terminate = false; 145 145 this.preemption_alarm = NULL; … … 152 152 } 153 153 154 void ^?{}(processor & this) {155 if( ! this.do_terminate ) {154 void ^?{}(processor & this) with( this ){ 155 if( ! do_terminate ) { 156 156 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 157 this.do_terminate = true;158 P( t his.terminated );159 pthread_join( this.kernel_thread, NULL );160 } 161 } 162 163 void ?{}(cluster & this) {164 (this.ready_queue){};165 ( this.ready_queue_lock ){};166 167 this.preemption = default_preemption();157 do_terminate = true; 158 P( terminated ); 159 pthread_join( kernel_thread, NULL ); 160 } 161 } 162 163 void ?{}(cluster & this) with( this ) { 164 ready_queue{}; 165 ready_queue_lock{}; 166 167 preemption = default_preemption(); 168 168 } 169 169 … … 238 238 // Once a thread has finished running, some of 239 239 // its final actions must be executed from the kernel 240 void finishRunning(processor * this) {241 if( this->finish.action_code == Release ) {242 unlock( * this->finish.lock );243 } 244 else if( this->finish.action_code == Schedule ) {245 ScheduleThread( th is->finish.thrd );246 } 247 else if( this->finish.action_code == Release_Schedule ) {248 unlock( * this->finish.lock );249 ScheduleThread( th is->finish.thrd );250 } 251 else if( this->finish.action_code == Release_Multi ) {252 for(int i = 0; i < this->finish.lock_count; i++) {253 unlock( * this->finish.locks[i] );240 void finishRunning(processor * this) with( this->finish ) { 241 if( action_code == Release ) { 242 unlock( *lock ); 243 } 244 else if( action_code == Schedule ) { 245 ScheduleThread( thrd ); 246 } 247 else if( action_code == Release_Schedule ) { 248 unlock( *lock ); 249 ScheduleThread( thrd ); 250 } 251 else if( action_code == Release_Multi ) { 252 for(int i = 0; i < lock_count; i++) { 253 unlock( *locks[i] ); 254 254 } 255 255 } 256 else if( this->finish.action_code == Release_Multi_Schedule ) {257 for(int i = 0; i < this->finish.lock_count; i++) {258 unlock( * this->finish.locks[i] );256 else if( action_code == Release_Multi_Schedule ) { 257 for(int i = 0; i < lock_count; i++) { 258 unlock( *locks[i] ); 259 259 } 260 for(int i = 0; i < th is->finish.thrd_count; i++) {261 ScheduleThread( th is->finish.thrds[i] );260 for(int i = 0; i < thrd_count; i++) { 261 ScheduleThread( thrds[i] ); 262 262 } 263 263 } 264 264 else { 265 assert( this->finish.action_code == No_Action);265 assert(action_code == No_Action); 266 266 } 267 267 } … … 332 332 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 333 333 334 lock( this_processor->cltr->ready_queue_lock __cfaabi_dbg_ctx2 ); 335 append( this_processor->cltr->ready_queue, thrd ); 336 unlock( this_processor->cltr->ready_queue_lock ); 337 338 verify( disable_preempt_count > 0 ); 339 } 340 341 thread_desc * nextThread(cluster * this) { 342 verify( disable_preempt_count > 0 ); 343 lock( this->ready_queue_lock __cfaabi_dbg_ctx2 ); 344 thread_desc * head = pop_head( this->ready_queue ); 345 unlock( this->ready_queue_lock ); 334 with( *this_processor->cltr ) { 335 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 336 append( ready_queue, thrd ); 337 unlock( ready_queue_lock ); 338 } 339 340 verify( disable_preempt_count > 0 ); 341 } 342 343 thread_desc * nextThread(cluster * this) with( *this ) { 344 verify( disable_preempt_count > 0 ); 345 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 346 thread_desc * head = pop_head( ready_queue ); 347 unlock( ready_queue_lock ); 346 348 verify( disable_preempt_count > 0 ); 347 349 return head; … … 359 361 disable_interrupts(); 360 362 this_processor->finish.action_code = Release; 361 this_processor->finish.lock = lock;363 this_processor->finish.lock = lock; 362 364 363 365 verify( disable_preempt_count > 0 ); … … 369 371 370 372 void BlockInternal( thread_desc * thrd ) { 371 assert(thrd);372 373 disable_interrupts(); 373 assert( thrd->self_cor.state != Halted );374 374 this_processor->finish.action_code = Schedule; 375 this_processor->finish.thrd = thrd;375 this_processor->finish.thrd = thrd; 376 376 377 377 verify( disable_preempt_count > 0 ); … … 386 386 disable_interrupts(); 387 387 this_processor->finish.action_code = Release_Schedule; 388 this_processor->finish.lock = lock;389 this_processor->finish.thrd = thrd;388 this_processor->finish.lock = lock; 389 this_processor->finish.thrd = thrd; 390 390 391 391 verify( disable_preempt_count > 0 ); … … 399 399 disable_interrupts(); 400 400 this_processor->finish.action_code = Release_Multi; 401 this_processor->finish.locks = locks;402 this_processor->finish.lock_count = count;401 this_processor->finish.locks = locks; 402 this_processor->finish.lock_count = count; 403 403 404 404 verify( disable_preempt_count > 0 ); … … 412 412 disable_interrupts(); 413 413 this_processor->finish.action_code = Release_Multi_Schedule; 414 this_processor->finish.locks = locks;415 this_processor->finish.lock_count = lock_count;416 this_processor->finish.thrds = thrds;417 this_processor->finish.thrd_count = thrd_count;414 this_processor->finish.locks = locks; 415 this_processor->finish.lock_count = lock_count; 416 this_processor->finish.thrds = thrds; 417 this_processor->finish.thrd_count = thrd_count; 418 418 419 419 verify( disable_preempt_count > 0 ); … … 427 427 verify( disable_preempt_count > 0 ); 428 428 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 429 this_processor->finish.lock = lock;430 this_processor->finish.thrd = thrd;429 this_processor->finish.lock = lock; 430 this_processor->finish.thrd = thrd; 431 431 432 432 suspend(); … … 579 579 void ^?{}(semaphore & this) {} 580 580 581 void P(semaphore & this) {582 lock( this.lock __cfaabi_dbg_ctx2 );583 this.count -= 1;584 if ( this.count < 0 ) {581 void P(semaphore & this) with( this ){ 582 lock( lock __cfaabi_dbg_ctx2 ); 583 count -= 1; 584 if ( count < 0 ) { 585 585 // queue current task 586 append( this.waiting, (thread_desc *)this_thread );586 append( waiting, (thread_desc *)this_thread ); 587 587 588 588 // atomically release spin lock and block 589 BlockInternal( & this.lock );589 BlockInternal( &lock ); 590 590 } 591 591 else { 592 unlock( this.lock );593 } 594 } 595 596 void V(semaphore & this) {592 unlock( lock ); 593 } 594 } 595 596 void V(semaphore & this) with( this ) { 597 597 thread_desc * thrd = NULL; 598 lock( this.lock __cfaabi_dbg_ctx2 );599 this.count += 1;600 if ( this.count <= 0 ) {598 lock( lock __cfaabi_dbg_ctx2 ); 599 count += 1; 600 if ( count <= 0 ) { 601 601 // remove task at head of waiting list 602 thrd = pop_head( this.waiting );603 } 604 605 unlock( this.lock );602 thrd = pop_head( waiting ); 603 } 604 605 unlock( lock ); 606 606 607 607 // make new owner -
src/libcfa/concurrency/preemption.c
r5b51f5e r65deb18 70 70 static pthread_t alarm_thread; // pthread handle to alarm thread 71 71 72 void ?{}(event_kernel_t & this) {73 (this.alarms){};74 (this.lock){};72 void ?{}(event_kernel_t & this) with( this ) { 73 alarms{}; 74 lock{}; 75 75 } 76 76 … … 159 159 // If counter reaches 0, execute any pending CtxSwitch 160 160 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 161 processor * proc= this_processor; // Cache the processor now since interrupts can start happening after the atomic add161 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 162 162 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 163 163 -
src/libcfa/concurrency/thread.c
r5b51f5e r65deb18 31 31 // Thread ctors and dtors 32 32 33 void ?{}(thread_desc& this) {34 (this.self_cor){};35 this.self_cor.name = "Anonymous Coroutine";36 this.self_mon.owner = &this;37 this.self_mon.recursion = 1;38 this.self_mon_p = &this.self_mon;39 this.next = NULL;33 void ?{}(thread_desc& this) with( this ) { 34 self_cor{}; 35 self_cor.name = "Anonymous Coroutine"; 36 self_mon.owner = &this; 37 self_mon.recursion = 1; 38 self_mon_p = &self_mon; 39 next = NULL; 40 40 41 (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 };41 monitors{ &self_mon_p, 1, (fptr_t)0 }; 42 42 } 43 43 44 void ^?{}(thread_desc& this) {45 ^ (this.self_cor){};44 void ^?{}(thread_desc& this) with( this ) { 45 ^self_cor{}; 46 46 } 47 47 48 48 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } ) 49 void ?{}( scoped(T)& this ) {50 (this.handle){};51 __thrd_start( this.handle);49 void ?{}( scoped(T)& this ) with( this ) { 50 handle{}; 51 __thrd_start(handle); 52 52 } 53 53 54 54 forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } ) 55 void ?{}( scoped(T)& this, P params ) {56 (this.handle){ params };57 __thrd_start( this.handle);55 void ?{}( scoped(T)& this, P params ) with( this ) { 56 handle{ params }; 57 __thrd_start(handle); 58 58 } 59 59 60 60 forall( dtype T | sized(T) | is_thread(T) ) 61 void ^?{}( scoped(T)& this ) {62 ^ (this.handle){};61 void ^?{}( scoped(T)& this ) with( this ) { 62 ^handle{}; 63 63 } 64 64 … … 68 68 void __thrd_start( T& this ) { 69 69 coroutine_desc* thrd_c = get_coroutine(this); 70 thread_desc *thrd_h = get_thread (this);70 thread_desc * thrd_h = get_thread (this); 71 71 thrd_c->last = this_coroutine; 72 72 -
src/libcfa/interpose.h
r5b51f5e r65deb18 16 16 #pragma once 17 17 18 void * interpose_symbol( const char* symbol, ,const char *version );18 void * interpose_symbol( const char* symbol, const char *version ); 19 19 20 20 extern __typeof__( abort ) libc_abort __attribute__(( noreturn ));
Note: See TracChangeset
for help on using the changeset viewer.