Changeset c81ebf9 for src/libcfa/concurrency/signal.c
- Timestamp:
- Jun 6, 2017, 11:45:13 AM (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:
- c5ac6d5
- Parents:
- 7b13aeb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/signal.c
r7b13aeb rc81ebf9 1 // -*- Mode: CFA -*- 2 // 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 // 5 // The contents of this file are covered under the licence agreement in the 6 // file "LICENCE" distributed with Cforall. 7 // 8 // signal.c -- 9 // 10 // Author : Thierry Delisle 11 // Created On : Mon Jun 5 14:20:42 2017 12 // Last Modified By : Thierry Delisle 13 // Last Modified On : -- 14 // Update Count : 0 15 // 16 17 #include "preemption.h" 18 19 extern "C" { 20 #include <signal.h> 21 } 22 23 #define __CFA_DEFAULT_PREEMPTION__ 10 24 25 __attribute__((weak)) unsigned int default_preemption() { 26 return __CFA_DEFAULT_PREEMPTION__; 27 } 28 29 static void preempt( processor * this ); 30 static void timeout( thread_desc * this ); 31 32 //============================================================================================= 33 // Kernel Preemption logic 34 //============================================================================================= 35 36 void kernel_start_preemption() { 37 38 } 39 40 void tick_preemption() { 41 alarm_list_t * alarms = &systemProcessor->alarms; 42 __cfa_time_t currtime = __kernel_get_time(); 43 while( alarms->head && alarms->head->alarm < currtime ) { 44 alarm_node_t * node = pop(alarms); 45 if( node->kernel_alarm ) { 46 preempt( node->proc ); 47 } 48 else { 49 timeout( node->thrd ); 50 } 51 52 if( node->period > 0 ) { 53 node->alarm += node->period; 54 insert( alarms, node ); 55 } 56 else { 57 node->set = false; 58 } 59 } 60 61 if( alarms->head ) { 62 __kernel_set_timer( alarms->head->alarm - currtime ); 63 } 64 } 65 66 void update_preemption( processor * this, __cfa_time_t duration ) { 67 // assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 ); 68 alarm_node_t * alarm = this->preemption_alarm; 69 70 // Alarms need to be enabled 71 if ( duration > 0 && !alarm->set ) { 72 alarm->alarm = __kernel_get_time() + duration; 73 alarm->period = duration; 74 register_self( alarm ); 75 } 76 // Zero duraction but alarm is set 77 else if ( duration == 0 && alarm->set ) { 78 unregister_self( alarm ); 79 alarm->alarm = 0; 80 alarm->period = 0; 81 } 82 // If alarm is different from previous, change it 83 else if ( duration > 0 && alarm->period != duration ) { 84 unregister_self( alarm ); 85 alarm->alarm = __kernel_get_time() + duration; 86 alarm->period = duration; 87 register_self( alarm ); 88 } 89 } 90 91 void ?{}( preemption_scope * this, processor * proc ) { 92 (&this->alarm){ proc }; 93 this->proc = proc; 94 this->proc->preemption_alarm = &this->alarm; 95 update_preemption( this->proc, this->proc->preemption ); 96 } 97 98 void ^?{}( preemption_scope * this ) { 99 update_preemption( this->proc, 0 ); 100 } 101 102 //============================================================================================= 103 // Kernel Signal logic 104 //============================================================================================= 105 106 static inline bool preemption_ready() { 107 return this_processor->disable_preempt_count == 0; 108 } 109 110 static inline void defer_ctxSwitch() { 111 this_processor->pending_preemption = true; 112 } 113 114 static inline void defer_alarm() { 115 systemProcessor->pending_alarm = true; 116 } 117 118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) { 119 if( preemption_ready() ) { 120 ScheduleInternal( this_processor->current_thread ); 121 } 122 else { 123 defer_ctxSwitch(); 124 } 125 } 126 127 void sigHandler_alarm( __attribute__((unused)) int sig ) { 128 if( try_lock( &systemProcessor->alarm_lock ) ) { 129 tick_preemption(); 130 unlock( &systemProcessor->alarm_lock ); 131 } 132 else { 133 defer_alarm(); 134 } 135 } 136 137 static void preempt( processor * this ) { 138 pthread_kill( this->kernel_thread, SIGUSR1 ); 139 } 140 141 static void timeout( thread_desc * this ) { 142 //TODO : implement waking threads 143 }
Note: See TracChangeset
for help on using the changeset viewer.