Changes in / [1a18423:e9a3b20b]
- Location:
- src
- Files:
-
- 1 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/alarm.c
r1a18423 re9a3b20b 16 16 17 17 extern "C" { 18 #include <errno.h>19 #include <stdio.h>20 #include <string.h>21 18 #include <time.h> 22 #include <unistd.h>23 19 #include <sys/time.h> 24 20 } … … 26 22 #include "alarm.h" 27 23 #include "kernel_private.h" 28 #include "libhdr.h"29 24 #include "preemption.h" 30 25 … … 36 31 timespec curr; 37 32 clock_gettime( CLOCK_REALTIME, &curr ); 38 __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 39 LIB_DEBUG_DO( 40 char text[256]; 41 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : current time is %lu\n", curr_time ); 42 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 43 ); 44 return curr_time; 33 return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 45 34 } 46 35 47 36 void __kernel_set_timer( __cfa_time_t alarm ) { 48 49 LIB_DEBUG_DO(50 char text[256];51 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : set timer to %lu\n", (__cfa_time_t)alarm );52 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );53 );54 55 37 itimerval val; 56 38 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds … … 89 71 } 90 72 91 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {92 alarm_node_t ** it = &this->head;93 while( (*it) ) {94 it = &(*it)->next;95 }96 97 return it == this->tail;98 })99 100 73 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 101 verify( !n->next );74 assert( !n->next ); 102 75 if( p == this->tail ) { 103 76 this->tail = &n->next; … … 107 80 } 108 81 *p = n; 109 110 verify( validate( this ) );111 82 } 112 83 … … 118 89 119 90 insert_at( this, n, it ); 120 121 verify( validate( this ) );122 91 } 123 92 … … 131 100 head->next = NULL; 132 101 } 133 verify( validate( this ) );134 102 return head; 135 103 } … … 137 105 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 138 106 verify( it ); 139 verify( (*it) == n );107 verify( (*it)->next == n ); 140 108 141 (*it) = n->next;109 (*it)->next = n->next; 142 110 if( !n-> next ) { 143 111 this->tail = it; 144 112 } 145 113 n->next = NULL; 146 147 verify( validate( this ) );148 114 } 149 115 150 116 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 151 117 alarm_node_t ** it = &this->head; 152 while( (*it) && (*it) != n ) {118 while( (*it) && (*it)->next != n ) { 153 119 it = &(*it)->next; 154 120 } 155 121 156 verify( validate( this ) );157 158 122 if( *it ) { remove_at( this, n, it ); } 159 160 verify( validate( this ) );161 123 } 162 124 163 125 void register_self( alarm_node_t * this ) { 164 126 disable_interrupts(); 165 verify( !systemProcessor->pending_alarm );127 assert( !systemProcessor->pending_alarm ); 166 128 lock( &systemProcessor->alarm_lock ); 167 129 { 168 verify( validate( &systemProcessor->alarms ) );169 bool first = !systemProcessor->alarms.head;170 171 130 insert( &systemProcessor->alarms, this ); 172 131 if( systemProcessor->pending_alarm ) { 173 132 tick_preemption(); 174 133 } 175 if( first ) {176 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );177 }178 134 } 179 135 unlock( &systemProcessor->alarm_lock ); 180 136 this->set = true; 181 enable_interrupts( __PRETTY_FUNCTION__);137 enable_interrupts(); 182 138 } 183 139 184 140 void unregister_self( alarm_node_t * this ) { 185 LIB_DEBUG_DO(186 char text[256];187 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : unregister %p start\n", this );188 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );189 );190 141 disable_interrupts(); 191 142 lock( &systemProcessor->alarm_lock ); 192 { 193 verify( validate( &systemProcessor->alarms ) ); 194 remove( &systemProcessor->alarms, this ); 195 } 143 remove( &systemProcessor->alarms, this ); 196 144 unlock( &systemProcessor->alarm_lock ); 197 145 disable_interrupts(); 198 146 this->set = false; 199 LIB_DEBUG_DO(200 len = snprintf( text, 256, "Kernel : unregister %p end\n", this );201 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );202 );203 147 } -
src/libcfa/concurrency/coroutine.c
r1a18423 re9a3b20b 32 32 #include "invoke.h" 33 33 34 extern volatilethread_local processor * this_processor;34 extern thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/invoke.c
r1a18423 re9a3b20b 30 30 extern void __suspend_internal(void); 31 31 extern void __leave_monitor_desc( struct monitor_desc * this ); 32 extern void disable_interrupts();33 extern void enable_interrupts( const char * );34 32 35 33 void CtxInvokeCoroutine( … … 69 67 struct monitor_desc* mon = &thrd->mon; 70 68 cor->state = Active; 71 enable_interrupts( __PRETTY_FUNCTION__ );72 69 73 70 // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this); 74 71 main( this ); 75 72 76 disable_interrupts();77 73 __leave_monitor_desc( mon ); 78 74 -
src/libcfa/concurrency/kernel
r1a18423 re9a3b20b 90 90 unsigned int preemption; 91 91 92 unsigned short disable_preempt_count; 93 92 94 bool pending_preemption; 93 94 char * last_enable;95 95 }; 96 96 -
src/libcfa/concurrency/kernel.c
r1a18423 re9a3b20b 59 59 // Global state 60 60 61 volatile thread_local processor * this_processor; 62 volatile thread_local unsigned short disable_preempt_count; 61 thread_local processor * this_processor; 63 62 64 63 coroutine_desc * this_coroutine(void) { … … 143 142 this->preemption_alarm = NULL; 144 143 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled 145 145 this->pending_preemption = false; 146 146 … … 154 154 (&this->terminated){}; 155 155 this->is_terminated = false; 156 this->preemption_alarm = NULL; 157 this->preemption = default_preemption(); 156 this->disable_preempt_count = 0; 158 157 this->pending_preemption = false; 159 this->kernel_thread = pthread_self();160 158 161 159 this->runner = runner; 162 LIB_DEBUG_PRINT_SAFE("Kernel : constructing systemprocessor context %p\n", runner);160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner); 163 161 runner{ this }; 164 162 } 165 166 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )167 163 168 164 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 172 168 173 169 (&this->proc){ cltr, runner }; 174 175 verify( validate( &this->alarms ) );176 170 } 177 171 … … 215 209 if(readyThread) 216 210 { 217 verify( disable_preempt_count > 0 );218 219 211 runThread(this, readyThread); 220 221 verify( disable_preempt_count > 0 );222 212 223 213 //Some actions need to be taken from the kernel … … 299 289 processor * proc = (processor *) arg; 300 290 this_processor = proc; 301 disable_preempt_count = 1;302 291 // SKULLDUGGERY: We want to create a context for the processor coroutine 303 292 // which is needed for the 2-step context switch. However, there is no reason … … 333 322 void start(processor * this) { 334 323 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 335 336 // SIGALRM must only be caught by the system processor 337 sigset_t old_mask; 338 bool is_system_proc = this_processor == &systemProcessor->proc; 339 if ( is_system_proc ) { 340 // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the 341 // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user 342 // processor, and toggle back (below) previous signal mask of the system processor. 343 344 sigset_t new_mask; 345 sigemptyset( &new_mask ); 346 sigemptyset( &old_mask ); 347 sigaddset( &new_mask, SIGALRM ); 348 349 if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) { 350 abortf( "internal error, sigprocmask" ); 351 } 352 353 assert( ! sigismember( &old_mask, SIGALRM ) ); 354 } 355 324 356 325 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 357 358 // Toggle back previous signal mask of system processor.359 if ( is_system_proc ) {360 if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {361 abortf( "internal error, sigprocmask" );362 } // if363 } // if364 326 365 327 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); … … 385 347 } 386 348 387 void BlockInternal() { 388 disable_interrupts(); 389 verify( disable_preempt_count > 0 ); 349 void ScheduleInternal() { 390 350 suspend(); 391 verify( disable_preempt_count > 0 ); 392 enable_interrupts( __PRETTY_FUNCTION__ ); 393 } 394 395 void BlockInternal( spinlock * lock ) { 396 disable_interrupts(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 397 354 this_processor->finish.action_code = Release; 398 355 this_processor->finish.lock = lock; 399 400 verify( disable_preempt_count > 0 );401 356 suspend(); 402 verify( disable_preempt_count > 0 ); 403 404 enable_interrupts( __PRETTY_FUNCTION__ ); 405 } 406 407 void BlockInternal( thread_desc * thrd ) { 408 disable_interrupts(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 409 360 this_processor->finish.action_code = Schedule; 410 361 this_processor->finish.thrd = thrd; 411 412 verify( disable_preempt_count > 0 );413 362 suspend(); 414 verify( disable_preempt_count > 0 ); 415 416 enable_interrupts( __PRETTY_FUNCTION__ ); 417 } 418 419 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 420 disable_interrupts(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 421 366 this_processor->finish.action_code = Release_Schedule; 422 367 this_processor->finish.lock = lock; 423 368 this_processor->finish.thrd = thrd; 424 425 verify( disable_preempt_count > 0 );426 369 suspend(); 427 verify( disable_preempt_count > 0 ); 428 429 enable_interrupts( __PRETTY_FUNCTION__ ); 430 } 431 432 void BlockInternal(spinlock ** locks, unsigned short count) { 433 disable_interrupts(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 434 373 this_processor->finish.action_code = Release_Multi; 435 374 this_processor->finish.locks = locks; 436 375 this_processor->finish.lock_count = count; 437 438 verify( disable_preempt_count > 0 );439 376 suspend(); 440 verify( disable_preempt_count > 0 ); 441 442 enable_interrupts( __PRETTY_FUNCTION__ ); 443 } 444 445 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 446 disable_interrupts(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 447 380 this_processor->finish.action_code = Release_Multi_Schedule; 448 381 this_processor->finish.locks = locks; … … 450 383 this_processor->finish.thrds = thrds; 451 384 this_processor->finish.thrd_count = thrd_count; 452 453 verify( disable_preempt_count > 0 );454 385 suspend(); 455 verify( disable_preempt_count > 0 );456 457 enable_interrupts( __PRETTY_FUNCTION__ );458 386 } 459 387 … … 475 403 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 476 404 405 // Enable preemption 406 kernel_start_preemption(); 407 477 408 // Initialize the system cluster 478 409 systemCluster = (cluster *)&systemCluster_storage; … … 494 425 this_processor->current_thread = mainThread; 495 426 this_processor->current_coroutine = &mainThread->cor; 496 disable_preempt_count = 1;497 498 // Enable preemption499 kernel_start_preemption();500 427 501 428 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX … … 508 435 // THE SYSTEM IS NOW COMPLETELY RUNNING 509 436 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 510 511 enable_interrupts( __PRETTY_FUNCTION__ );512 437 } 513 438 514 439 void kernel_shutdown(void) { 515 440 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 516 517 disable_interrupts();518 441 519 442 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 524 447 525 448 // THE SYSTEM IS NOW COMPLETELY STOPPED 526 527 // Disable preemption528 kernel_stop_preemption();529 449 530 450 // Destroy the system processor and its context in reverse order of construction … … 630 550 if( !this->cond ) { 631 551 append( &this->blocked, this_thread() ); 632 BlockInternal( &this->lock ); 633 } 634 else { 635 unlock( &this->lock ); 636 } 552 ScheduleInternal( &this->lock ); 553 lock( &this->lock ); 554 } 555 unlock( &this->lock ); 637 556 } 638 557 … … 642 561 this->cond = true; 643 562 644 disable_interrupts();645 563 thread_desc * it; 646 564 while( it = pop_head( &this->blocked) ) { 647 565 ScheduleThread( it ); 648 566 } 649 enable_interrupts( __PRETTY_FUNCTION__ );650 567 } 651 568 unlock( &this->lock ); -
src/libcfa/concurrency/kernel_private.h
r1a18423 re9a3b20b 30 30 thread_desc * nextThread(cluster * this); 31 31 32 void BlockInternal(void);33 void BlockInternal(spinlock * lock);34 void BlockInternal(thread_desc * thrd);35 void BlockInternal(spinlock * lock, thread_desc * thrd);36 void BlockInternal(spinlock ** locks, unsigned short count);37 void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);32 void ScheduleInternal(void); 33 void ScheduleInternal(spinlock * lock); 34 void ScheduleInternal(thread_desc * thrd); 35 void ScheduleInternal(spinlock * lock, thread_desc * thrd); 36 void ScheduleInternal(spinlock ** locks, unsigned short count); 37 void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count); 38 38 39 39 //----------------------------------------------------------------------------- … … 60 60 extern cluster * systemCluster; 61 61 extern system_proc_t * systemProcessor; 62 extern volatile thread_local processor * this_processor; 63 extern volatile thread_local unsigned short disable_preempt_count; 62 extern thread_local processor * this_processor; 64 63 65 extern "C" { 66 void disable_interrupts(); 67 void enable_interrupts_noRF(); 68 void enable_interrupts( const char * ); 64 static inline void disable_interrupts() { 65 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 66 assert( prev != (unsigned short) -1 ); 67 } 68 69 static inline void enable_interrupts_noRF() { 70 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 71 verify( prev != (unsigned short) 0 ); 72 } 73 74 static inline void enable_interrupts() { 75 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 76 verify( prev != (unsigned short) 0 ); 77 if( prev == 1 && this_processor->pending_preemption ) { 78 ScheduleInternal( this_processor->current_thread ); 79 this_processor->pending_preemption = false; 80 } 69 81 } 70 82 -
src/libcfa/concurrency/monitor.c
r1a18423 re9a3b20b 63 63 append( &this->entry_queue, thrd ); 64 64 LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 65 BlockInternal( &this->lock );66 67 // BlockInternal will unlock spinlock, no need to unlock ourselves65 ScheduleInternal( &this->lock ); 66 67 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 68 68 return; 69 69 } … … 170 170 unsigned short count = this->monitor_count; 171 171 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 172 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal172 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 173 173 174 174 LIB_DEBUG_PRINT_SAFE("count %i\n", count); … … 208 208 209 209 // Everything is ready to go to sleep 210 BlockInternal( locks, count, threads, thread_count );210 ScheduleInternal( locks, count, threads, thread_count ); 211 211 212 212 … … 281 281 unsigned short count = this->monitor_count; 282 282 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 283 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal283 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 284 284 285 285 lock_all( this->monitors, locks, count ); … … 309 309 310 310 //Everything is ready to go to sleep 311 BlockInternal( locks, count, &signallee, 1 );311 ScheduleInternal( locks, count, &signallee, 1 ); 312 312 313 313 … … 339 339 // unsigned short count = this->current_monitor_count; 340 340 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 342 342 343 343 // lock_all( this->current_monitors, locks, count ); … … 348 348 349 349 // // // Everything is ready to go to sleep 350 // // BlockInternal( locks, count, threads, thread_count );350 // // ScheduleInternal( locks, count, threads, thread_count ); 351 351 352 352 -
src/libcfa/concurrency/preemption.c
r1a18423 re9a3b20b 17 17 #include "preemption.h" 18 18 19 20 19 extern "C" { 21 #include <errno.h>22 #define __USE_GNU23 20 #include <signal.h> 24 #undef __USE_GNU25 #include <stdio.h>26 #include <string.h>27 #include <unistd.h>28 21 } 29 22 30 #include "libhdr.h" 31 32 #define __CFA_DEFAULT_PREEMPTION__ 10000 23 #define __CFA_DEFAULT_PREEMPTION__ 10 33 24 34 25 __attribute__((weak)) unsigned int default_preemption() { … … 36 27 } 37 28 38 #define __CFA_SIGCXT__ ucontext_t *39 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt40 41 29 static void preempt( processor * this ); 42 30 static void timeout( thread_desc * this ); 43 44 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );45 void sigHandler_alarm ( __CFA_SIGPARMS__ );46 47 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );48 31 49 32 //============================================================================================= … … 52 35 53 36 void kernel_start_preemption() { 54 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n"); 55 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); 56 __kernel_sigaction( SIGALRM, sigHandler_alarm , SA_SIGINFO ); 37 57 38 } 58 39 59 void kernel_stop_preemption() {60 //Block all signals, we are no longer in a position to handle them61 sigset_t mask;62 sigfillset( &mask );63 sigprocmask( SIG_BLOCK, &mask, NULL );64 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");65 66 assert( !systemProcessor->alarms.head );67 assert( systemProcessor->alarms.tail == &systemProcessor->alarms.head );68 }69 70 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )71 72 40 void tick_preemption() { 73 LIB_DEBUG_DO(74 char text[256];75 __attribute__((unused)) int len = snprintf( text, 256, "Ticking preemption\n" );76 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );77 );78 79 41 alarm_list_t * alarms = &systemProcessor->alarms; 80 42 __cfa_time_t currtime = __kernel_get_time(); 81 43 while( alarms->head && alarms->head->alarm < currtime ) { 82 44 alarm_node_t * node = pop(alarms); 83 LIB_DEBUG_DO(84 len = snprintf( text, 256, "Ticking %p\n", node );85 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );86 );87 45 if( node->kernel_alarm ) { 88 46 preempt( node->proc ); … … 92 50 } 93 51 94 LIB_DEBUG_DO( assert( validate( alarms ) ) );95 96 52 if( node->period > 0 ) { 97 node->alarm = currtime +node->period;53 node->alarm += node->period; 98 54 insert( alarms, node ); 99 55 } … … 106 62 __kernel_set_timer( alarms->head->alarm - currtime ); 107 63 } 108 109 verify( validate( alarms ) );110 LIB_DEBUG_DO(111 len = snprintf( text, 256, "Ticking preemption done\n" );112 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );113 );114 64 } 115 65 116 66 void update_preemption( processor * this, __cfa_time_t duration ) { 117 LIB_DEBUG_DO( 118 char text[256]; 119 __attribute__((unused)) int len = snprintf( text, 256, "Processor : %p updating preemption to %lu\n", this, duration ); 120 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 121 ); 122 67 // assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 ); 123 68 alarm_node_t * alarm = this->preemption_alarm; 124 duration *= 1000;125 69 126 70 // Alarms need to be enabled … … 153 97 154 98 void ^?{}( preemption_scope * this ) { 155 disable_interrupts();156 157 99 update_preemption( this->proc, 0 ); 158 100 } … … 162 104 //============================================================================================= 163 105 164 extern "C" {165 void disable_interrupts() {166 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );167 verify( new_val < (unsigned short)65_000 );168 verify( new_val != (unsigned short) 0 );169 }170 171 void enable_interrupts_noRF() {172 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );173 verify( prev != (unsigned short) 0 );174 }175 176 void enable_interrupts( const char * func ) {177 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );178 verify( prev != (unsigned short) 0 );179 if( prev == 1 && this_processor->pending_preemption ) {180 this_processor->pending_preemption = false;181 LIB_DEBUG_DO(182 char text[256];183 __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch on %p\n", this_processor );184 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );185 );186 BlockInternal( this_processor->current_thread );187 }188 189 this_processor->last_enable = func;190 }191 }192 193 static inline void signal_unblock( bool alarm ) {194 sigset_t mask;195 sigemptyset( &mask );196 sigaddset( &mask, SIGUSR1 );197 198 if( alarm ) sigaddset( &mask, SIGALRM );199 200 if ( sigprocmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {201 abortf( "internal error, sigprocmask" );202 } // if203 }204 205 106 static inline bool preemption_ready() { 206 return disable_preempt_count == 0;107 return this_processor->disable_preempt_count == 0; 207 108 } 208 109 … … 215 116 } 216 117 217 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 218 219 LIB_DEBUG_DO( 220 char text[256]; 221 __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP])); 222 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 223 ); 224 225 signal_unblock( false ); 118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) { 226 119 if( preemption_ready() ) { 227 LIB_DEBUG_DO( 228 len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread %p on %p\n", this_processor->current_thread, this_processor ); 229 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 230 ); 231 BlockInternal( this_processor->current_thread ); 120 ScheduleInternal( this_processor->current_thread ); 232 121 } 233 122 else { 234 LIB_DEBUG_DO(235 len = snprintf( text, 256, "Ctx Switch IRH : Defering\n" );236 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );237 );238 123 defer_ctxSwitch(); 239 124 } 240 125 } 241 126 242 void sigHandler_alarm( __CFA_SIGPARMS__ ) { 243 244 LIB_DEBUG_DO( 245 char text[256]; 246 __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]) ); 247 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 248 ); 249 250 signal_unblock( true ); 127 void sigHandler_alarm( __attribute__((unused)) int sig ) { 251 128 if( try_lock( &systemProcessor->alarm_lock ) ) { 252 129 tick_preemption(); … … 256 133 defer_alarm(); 257 134 } 258 259 if( preemption_ready() && this_processor->pending_preemption ) {260 LIB_DEBUG_DO(261 len = snprintf( text, 256, "Alarm IRH : Blocking thread\n" );262 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );263 );264 this_processor->pending_preemption = false;265 BlockInternal( this_processor->current_thread );266 }267 135 } 268 136 269 137 static void preempt( processor * this ) { 270 LIB_DEBUG_DO( 271 char text[256]; 272 __attribute__((unused)) int len = snprintf( text, 256, "Processor : signalling %p\n", this ); 273 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 274 ); 275 276 if( this != systemProcessor ) { 277 pthread_kill( this->kernel_thread, SIGUSR1 ); 278 } 279 else { 280 defer_ctxSwitch(); 281 } 138 pthread_kill( this->kernel_thread, SIGUSR1 ); 282 139 } 283 140 … … 285 142 //TODO : implement waking threads 286 143 } 287 288 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {289 struct sigaction act;290 291 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;292 sigemptyset( &act.sa_mask );293 sigaddset( &act.sa_mask, SIGALRM ); // disabled during signal handler294 sigaddset( &act.sa_mask, SIGUSR1 );295 296 act.sa_flags = flags;297 298 if ( sigaction( sig, &act, NULL ) == -1 ) {299 // THE KERNEL IS NOT STARTED SO CALL NO uC++ ROUTINES!300 char helpText[256];301 __attribute__((unused)) int len = snprintf( helpText, 256, " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",302 sig, handler, flags, errno, strerror( errno ) );303 LIB_DEBUG_WRITE( STDERR_FILENO, helpText, len );304 _exit( EXIT_FAILURE );305 } // if306 } -
src/libcfa/concurrency/thread.c
r1a18423 re9a3b20b 28 28 } 29 29 30 extern volatilethread_local processor * this_processor;30 extern thread_local processor * this_processor; 31 31 32 32 //----------------------------------------------------------------------------- … … 84 84 85 85 void yield( void ) { 86 BlockInternal( this_processor->current_thread );86 ScheduleInternal( this_processor->current_thread ); 87 87 } 88 88 -
src/libcfa/libhdr/libdebug.h
r1a18423 re9a3b20b 19 19 #ifdef __CFA_DEBUG__ 20 20 #define LIB_DEBUG_DO(x) x 21 #define LIB_NO_DEBUG_DO(x) 21 #define LIB_NO_DEBUG_DO(x) ((void)0) 22 22 #else 23 #define LIB_DEBUG_DO(x) 24 #define LIB_NO_DEBUG_DO(x) x 23 #define LIB_DEBUG_DO(x) ((void)0) 24 #define LIB_NO_DEBUG_DO(x) x 25 25 #endif 26 26
Note: See TracChangeset
for help on using the changeset viewer.