Changeset b826e6b for src/libcfa/concurrency/alarm.c
- Timestamp:
- Jul 19, 2017, 11:49:33 AM (8 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:
- 9cc0472
- Parents:
- fea3faa (diff), a57cb58 (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
-
src/libcfa/concurrency/alarm.c
rfea3faa rb826e6b 16 16 17 17 extern "C" { 18 #include <errno.h> 19 #include <stdio.h> 20 #include <string.h> 18 21 #include <time.h> 22 #include <unistd.h> 19 23 #include <sys/time.h> 20 24 } 25 26 #include "libhdr.h" 21 27 22 28 #include "alarm.h" … … 25 31 26 32 //============================================================================================= 33 // time type 34 //============================================================================================= 35 36 #define one_second 1_000_000_000ul 37 #define one_milisecond 1_000_000ul 38 #define one_microsecond 1_000ul 39 #define one_nanosecond 1ul 40 41 __cfa_time_t zero_time = { 0 }; 42 43 void ?{}( __cfa_time_t * this ) { this->val = 0; } 44 void ?{}( __cfa_time_t * this, zero_t zero ) { this->val = 0; } 45 46 void ?{}( itimerval * this, __cfa_time_t * alarm ) { 47 this->it_value.tv_sec = alarm->val / one_second; // seconds 48 this->it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds 49 this->it_interval.tv_sec = 0; 50 this->it_interval.tv_usec = 0; 51 } 52 53 54 void ?{}( __cfa_time_t * this, timespec * curr ) { 55 uint64_t secs = curr->tv_sec; 56 uint64_t nsecs = curr->tv_nsec; 57 this->val = (secs * one_second) + nsecs; 58 } 59 60 __cfa_time_t ?=?( __cfa_time_t * this, zero_t rhs ) { 61 this->val = 0; 62 return *this; 63 } 64 65 __cfa_time_t from_s ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; } 66 __cfa_time_t from_ms( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000ul; return ret; } 67 __cfa_time_t from_us( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000ul; return ret; } 68 __cfa_time_t from_ns( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1ul; return ret; } 69 70 //============================================================================================= 27 71 // Clock logic 28 72 //============================================================================================= … … 31 75 timespec curr; 32 76 clock_gettime( CLOCK_REALTIME, &curr ); 33 return ( (__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;77 return (__cfa_time_t){ &curr }; 34 78 } 35 79 36 80 void __kernel_set_timer( __cfa_time_t alarm ) { 37 itimerval val; 38 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds 39 val.it_value.tv_usec = (alarm % TIMEGRAN) / ( TIMEGRAN / 1_000_000L ); // microseconds 40 val.it_interval.tv_sec = 0; 41 val.it_interval.tv_usec = 0; 81 itimerval val = { &alarm }; 42 82 setitimer( ITIMER_REAL, &val, NULL ); 43 83 } … … 47 87 //============================================================================================= 48 88 49 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {89 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 50 90 this->thrd = thrd; 51 91 this->alarm = alarm; … … 56 96 } 57 97 58 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {98 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 59 99 this->proc = proc; 60 100 this->alarm = alarm; … … 71 111 } 72 112 113 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) { 114 alarm_node_t ** it = &this->head; 115 while( (*it) ) { 116 it = &(*it)->next; 117 } 118 119 return it == this->tail; 120 }) 121 73 122 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 74 assert( !n->next );123 verify( !n->next ); 75 124 if( p == this->tail ) { 76 125 this->tail = &n->next; … … 80 129 } 81 130 *p = n; 131 132 verify( validate( this ) ); 82 133 } 83 134 … … 89 140 90 141 insert_at( this, n, it ); 142 143 verify( validate( this ) ); 91 144 } 92 145 … … 100 153 head->next = NULL; 101 154 } 155 verify( validate( this ) ); 102 156 return head; 103 157 } … … 105 159 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 106 160 verify( it ); 107 verify( (*it) ->next== n );108 109 (*it) ->next= n->next;161 verify( (*it) == n ); 162 163 (*it) = n->next; 110 164 if( !n-> next ) { 111 165 this->tail = it; 112 166 } 113 167 n->next = NULL; 168 169 verify( validate( this ) ); 114 170 } 115 171 116 172 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 117 173 alarm_node_t ** it = &this->head; 118 while( (*it) && (*it) ->next!= n ) {174 while( (*it) && (*it) != n ) { 119 175 it = &(*it)->next; 120 176 } 121 177 178 verify( validate( this ) ); 179 122 180 if( *it ) { remove_at( this, n, it ); } 181 182 verify( validate( this ) ); 123 183 } 124 184 125 185 void register_self( alarm_node_t * this ) { 186 alarm_list_t * alarms = &event_kernel->alarms; 187 126 188 disable_interrupts(); 127 assert( !systemProcessor->pending_alarm ); 128 lock( &systemProcessor->alarm_lock ); 189 lock( &event_kernel->lock DEBUG_CTX2 ); 129 190 { 130 insert( &systemProcessor->alarms, this ); 131 if( systemProcessor->pending_alarm ) { 132 tick_preemption(); 191 verify( validate( alarms ) ); 192 bool first = !alarms->head; 193 194 insert( alarms, this ); 195 if( first ) { 196 __kernel_set_timer( alarms->head->alarm - __kernel_get_time() ); 133 197 } 134 198 } 135 unlock( & systemProcessor->alarm_lock );199 unlock( &event_kernel->lock ); 136 200 this->set = true; 137 enable_interrupts( );201 enable_interrupts( DEBUG_CTX ); 138 202 } 139 203 140 204 void unregister_self( alarm_node_t * this ) { 141 205 disable_interrupts(); 142 lock( &systemProcessor->alarm_lock ); 143 remove( &systemProcessor->alarms, this ); 144 unlock( &systemProcessor->alarm_lock ); 145 disable_interrupts(); 206 lock( &event_kernel->lock DEBUG_CTX2 ); 207 { 208 verify( validate( &event_kernel->alarms ) ); 209 remove( &event_kernel->alarms, this ); 210 } 211 unlock( &event_kernel->lock ); 212 enable_interrupts( DEBUG_CTX ); 146 213 this->set = false; 147 214 }
Note:
See TracChangeset
for help on using the changeset viewer.