- File:
-
- 1 edited
-
libcfa/src/concurrency/preemption.cfa (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
rc457dc41 ra3821fa 18 18 19 19 #include "preemption.hfa" 20 21 20 #include <assert.h> 22 21 … … 27 26 #include <limits.h> // PTHREAD_STACK_MIN 28 27 29 #include "bits/debug.hfa"30 28 #include "bits/signal.hfa" 31 29 #include "kernel_private.hfa" … … 107 105 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) { 108 106 if( ! & (*alarms)`first ) return 0p; // If no alarms return null 109 if( (*alarms)`first. timeval>= currtime ) return 0p; // If alarms head not expired return null107 if( (*alarms)`first.alarm >= currtime ) return 0p; // If alarms head not expired return null 110 108 return pop(alarms); // Otherwise just pop head 111 109 } … … 143 141 if( period > 0 ) { 144 142 __cfadbg_print_buffer_local( preemption, " KERNEL: alarm period is %lu.\n", period`ns ); 145 node-> timeval = currtime + period;// Alarm is periodic, add currtime to it (used cached current time)143 node->alarm = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) 146 144 insert( alarms, node ); // Reinsert the node for the next time it triggers 147 145 } … … 150 148 // If there are still alarms pending, reset the timer 151 149 if( & (*alarms)`first ) { 152 Duration delta = (*alarms)`first.timeval - currtime; 153 __kernel_set_timer( delta ); 150 Duration delta = (*alarms)`first.alarm - currtime; 151 Duration capped = max(delta, 50`us); 152 __kernel_set_timer( capped ); 154 153 } 155 154 } … … 161 160 // Alarms need to be enabled 162 161 if ( duration > 0 && ! alarm->set ) { 163 alarm-> initial =duration;164 alarm->period = duration;162 alarm->alarm = __kernel_get_time() + duration; 163 alarm->period = duration; 165 164 register_self( alarm ); 166 165 } … … 168 167 else if ( duration == 0 && alarm->set ) { 169 168 unregister_self( alarm ); 170 alarm-> initial= 0;171 alarm->period = 0;169 alarm->alarm = 0; 170 alarm->period = 0; 172 171 } 173 172 // If alarm is different from previous, change it 174 173 else if ( duration > 0 && alarm->period != duration ) { 175 174 unregister_self( alarm ); 176 alarm-> initial =duration;177 alarm->period = duration;175 alarm->alarm = __kernel_get_time() + duration; 176 alarm->period = duration; 178 177 register_self( alarm ); 179 178 } … … 600 599 601 600 // Notify the alarm thread of the shutdown 602 sigval val; 603 val.sival_int = 0; 601 sigval val = { 1 }; 604 602 pthread_sigqueue( alarm_thread, SIGALRM, val ); 605 603 … … 621 619 // Used by thread to control when they want to receive preemption signals 622 620 void ?{}( preemption_scope & this, processor * proc ) { 623 (this.alarm){ proc, 0`s, 0`s };621 (this.alarm){ proc, (Time){ 0 }, 0`s }; 624 622 this.proc = proc; 625 623 this.proc->preemption_alarm = &this.alarm; … … 689 687 // Waits on SIGALRM and send SIGUSR1 to whom ever needs it 690 688 static void * alarm_loop( __attribute__((unused)) void * args ) { 691 unsigned id = register_proc_id(); 689 __processor_id_t id; 690 register_proc_id(&id); 691 __cfaabi_tls.this_proc_id = &id; 692 692 693 693 694 // Block sigalrms to control when they arrive … … 706 707 siginfo_t info; 707 708 int sig = sigwaitinfo( &mask, &info ); 708 709 __cfadbg_print_buffer_decl ( preemption, " KERNEL: sigwaitinfo returned %d, c: %d, v: %d\n", sig, info.si_code, info.si_value.sival_int );710 __cfadbg_print_buffer_local( preemption, " KERNEL: SI_QUEUE %d, SI_TIMER %d, SI_KERNEL %d\n", SI_QUEUE, SI_TIMER, SI_KERNEL );711 709 712 710 if( sig < 0 ) { … … 716 714 case EAGAIN : 717 715 case EINTR : 718 {__cfa dbg_print_buffer_local( preemption," KERNEL: Spurious wakeup %d.\n", err );}716 {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );} 719 717 continue; 720 718 case EINVAL : … … 728 726 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 729 727 728 // __cfaabi_dbg_print_safe( "Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int ); 730 729 // Switch on the code (a.k.a. the sender) to 731 730 switch( info.si_code ) 732 731 { 733 // Signal was not sent by the kernel but by an other thread734 case SI_QUEUE:735 // other threads may signal the alarm thread to shut it down736 // or to manual cause the preemption tick737 // use info.si_value and handle the case here738 switch( info.si_value.sival_int ) {739 case 0:740 goto EXIT;741 default:742 abort( "SI_QUEUE with val %d", info.si_value.sival_int);743 }744 // fallthrough745 732 // Timers can apparently be marked as sent for the kernel 746 733 // In either case, tick preemption … … 752 739 unlock( event_kernel->lock ); 753 740 break; 741 // Signal was not sent by the kernel but by an other thread 742 case SI_QUEUE: 743 // For now, other thread only signal the alarm thread to shut it down 744 // If this needs to change use info.si_value and handle the case here 745 goto EXIT; 754 746 } 755 747 } … … 757 749 EXIT: 758 750 __cfaabi_dbg_print_safe( "Kernel : Preemption thread stopping\n" ); 759 unregister_proc_id(id);751 register_proc_id(&id); 760 752 761 753 return 0p;
Note:
See TracChangeset
for help on using the changeset viewer.