Changeset 3b56166 for libcfa/src/concurrency/kernel.cfa
- Timestamp:
- Feb 10, 2020, 11:17:38 AM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 3966d9a, 41efd33
- Parents:
- 807a632 (diff), d231700 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r807a632 r3b56166 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Jun 20 17:21:23 201913 // Update Count : 2512 // Last Modified On : Tue Feb 4 13:03:15 2020 13 // Update Count : 58 14 14 // 15 15 … … 26 26 #include <signal.h> 27 27 #include <unistd.h> 28 #include <limits.h> // PTHREAD_STACK_MIN 29 #include <sys/mman.h> // mprotect 28 30 } 29 31 … … 40 42 //----------------------------------------------------------------------------- 41 43 // Some assembly required 42 #if 44 #if defined( __i386 ) 43 45 #define CtxGet( ctx ) \ 44 46 __asm__ volatile ( \ … … 123 125 124 126 extern "C" { 125 struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;127 struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters; 126 128 } 127 129 … … 131 133 // Global state 132 134 thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) = { 135 NULL, // cannot use 0p 133 136 NULL, 134 NULL,135 { 1, false, false }137 { 1, false, false }, 138 6u //this should be seeded better but due to a bug calling rdtsc doesn't work 136 139 }; 137 140 … … 139 142 // Struct to steal stack 140 143 struct current_stack_info_t { 141 __stack_t * storage; // pointer to stack object142 void * base;// base of stack143 void * limit;// stack grows towards stack limit144 void * context;// address of cfa_context_t144 __stack_t * storage; // pointer to stack object 145 void * base; // base of stack 146 void * limit; // stack grows towards stack limit 147 void * context; // address of cfa_context_t 145 148 }; 146 149 … … 171 174 name = "Main Thread"; 172 175 state = Start; 173 starter = NULL;174 last = NULL;175 cancellation = NULL;176 starter = 0p; 177 last = 0p; 178 cancellation = 0p; 176 179 } 177 180 … … 184 187 self_mon.recursion = 1; 185 188 self_mon_p = &self_mon; 186 next = NULL;187 188 node.next = NULL;189 node.prev = NULL;189 next = 0p; 190 191 node.next = 0p; 192 node.prev = 0p; 190 193 doregister(curr_cluster, this); 191 194 … … 206 209 207 210 static void start(processor * this); 208 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {211 void ?{}(processor & this, const char name[], cluster & cltr) with( this ) { 209 212 this.name = name; 210 213 this.cltr = &cltr; 211 214 terminated{ 0 }; 212 215 do_terminate = false; 213 preemption_alarm = NULL;216 preemption_alarm = 0p; 214 217 pending_preemption = false; 215 218 runner.proc = &this; … … 231 234 } 232 235 233 pthread_join( kernel_thread, NULL ); 234 } 235 236 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) { 236 pthread_join( kernel_thread, 0p ); 237 free( this.stack ); 238 } 239 240 void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) { 237 241 this.name = name; 238 242 this.preemption_rate = preemption_rate; … … 260 264 //Main of the processor contexts 261 265 void main(processorCtx_t & runner) { 266 // Because of a bug, we couldn't initialized the seed on construction 267 // Do it here 268 kernelTLS.rand_seed ^= rdtscl(); 269 262 270 processor * this = runner.proc; 263 271 verify(this); … … 273 281 __cfaabi_dbg_print_safe("Kernel : core %p started\n", this); 274 282 275 thread_desc * readyThread = NULL; 276 for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) 277 { 283 thread_desc * readyThread = 0p; 284 for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) { 278 285 readyThread = nextThread( this->cltr ); 279 286 280 if(readyThread) 281 { 287 if(readyThread) { 282 288 verify( ! kernelTLS.preemption_state.enabled ); 283 289 … … 290 296 291 297 spin_count = 0; 292 } 293 else 294 { 298 } else { 295 299 // spin(this, &spin_count); 296 300 halt(this); … … 405 409 processor * proc = (processor *) arg; 406 410 kernelTLS.this_processor = proc; 407 kernelTLS.this_thread = NULL;411 kernelTLS.this_thread = 0p; 408 412 kernelTLS.preemption_state.[enabled, disable_count] = [false, 1]; 409 413 // SKULLDUGGERY: We want to create a context for the processor coroutine … … 418 422 419 423 //Set global state 420 kernelTLS.this_thread = NULL;424 kernelTLS.this_thread = 0p; 421 425 422 426 //We now have a proper context from which to schedule threads … … 434 438 __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner); 435 439 436 return NULL; 440 return 0p; 441 } 442 443 static void Abort( int ret, const char func[] ) { 444 if ( ret ) { // pthread routines return errno values 445 abort( "%s : internal error, error(%d) %s.", func, ret, strerror( ret ) ); 446 } // if 447 } // Abort 448 449 void * create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) { 450 pthread_attr_t attr; 451 452 Abort( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute 453 454 size_t stacksize; 455 // default stack size, normally defined by shell limit 456 Abort( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" ); 457 assert( stacksize >= PTHREAD_STACK_MIN ); 458 459 void * stack; 460 __cfaabi_dbg_debug_do( 461 stack = memalign( __page_size, stacksize + __page_size ); 462 // pthread has no mechanism to create the guard page in user supplied stack. 463 if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) { 464 abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) ); 465 } // if 466 ); 467 __cfaabi_dbg_no_debug_do( 468 stack = malloc( stacksize ); 469 ); 470 471 Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 472 473 Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" ); 474 return stack; 437 475 } 438 476 … … 440 478 __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this); 441 479 442 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );480 this->stack = create_pthread( &this->kernel_thread, CtxInvokeProcessor, (void *)this ); 443 481 444 482 __cfaabi_dbg_print_safe("Kernel : core %p started\n", this); … … 452 490 verify( ! kernelTLS.preemption_state.enabled ); 453 491 492 kernelTLS.this_thread->curr_cor = dst; 454 493 __stack_prepare( &dst->stack, 65000 ); 455 CtxStart( &this->runner, CtxInvokeCoroutine);494 CtxStart(main, dst, this->runner, CtxInvokeCoroutine); 456 495 457 496 verify( ! kernelTLS.preemption_state.enabled ); … … 468 507 // when CtxSwitch returns we are back in the src coroutine 469 508 509 mainThread->curr_cor = &mainThread->self_cor; 510 470 511 // set state of new coroutine to active 471 512 src->state = Active; … … 497 538 verify( ! kernelTLS.preemption_state.enabled ); 498 539 499 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );540 verifyf( thrd->next == 0p, "Expected null got %p", thrd->next ); 500 541 501 542 with( *thrd->curr_cluster ) { … … 676 717 void ?{}(processorCtx_t & this, processor * proc) { 677 718 (this.__cor){ "Processor" }; 678 this.__cor.starter = NULL;719 this.__cor.starter = 0p; 679 720 this.proc = proc; 680 721 } … … 685 726 terminated{ 0 }; 686 727 do_terminate = false; 687 preemption_alarm = NULL;728 preemption_alarm = 0p; 688 729 pending_preemption = false; 689 730 kernel_thread = pthread_self(); … … 803 844 sigemptyset( &mask ); 804 845 sigaddset( &mask, SIGALRM ); // block SIGALRM signals 805 sigsuspend( &mask ); // block the processor to prevent further damage during abort 806 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 846 sigaddset( &mask, SIGUSR1 ); // block SIGALRM signals 847 sigsuspend( &mask ); // block the processor to prevent further damage during abort 848 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 807 849 } 808 850 else { … … 819 861 if(thrd) { 820 862 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd ); 821 __cfaabi_ dbg_bits_write(abort_text, len );863 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 822 864 823 865 if ( &thrd->self_cor != thrd->curr_cor ) { 824 866 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", thrd->curr_cor->name, thrd->curr_cor ); 825 __cfaabi_ dbg_bits_write(abort_text, len );867 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 826 868 } 827 869 else { 828 __cfaabi_ dbg_bits_write(".\n", 2 );870 __cfaabi_bits_write( STDERR_FILENO, ".\n", 2 ); 829 871 } 830 872 } 831 873 else { 832 874 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" ); 833 __cfaabi_ dbg_bits_write(abort_text, len );875 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 834 876 } 835 877 } … … 842 884 843 885 extern "C" { 844 void __cfaabi_ dbg_bits_acquire() {886 void __cfaabi_bits_acquire() { 845 887 lock( kernel_debug_lock __cfaabi_dbg_ctx2 ); 846 888 } 847 889 848 void __cfaabi_ dbg_bits_release() {890 void __cfaabi_bits_release() { 849 891 unlock( kernel_debug_lock ); 850 892 } … … 879 921 880 922 void V(semaphore & this) with( this ) { 881 thread_desc * thrd = NULL;923 thread_desc * thrd = 0p; 882 924 lock( lock __cfaabi_dbg_ctx2 ); 883 925 count += 1; … … 939 981 __cfaabi_dbg_debug_do( 940 982 extern "C" { 941 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {983 void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) { 942 984 this.prev_name = prev_name; 943 985 this.prev_thrd = kernelTLS.this_thread;
Note:
See TracChangeset
for help on using the changeset viewer.