Changes in src/libcfa/concurrency/alarm.c [969b3fe:4aa2fb2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/alarm.c
r969b3fe r4aa2fb2 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 } 25 26 #include "libhdr.h"27 21 28 22 #include "alarm.h" 29 23 #include "kernel_private.h" 30 24 #include "preemption.h" 31 32 //=============================================================================================33 // time type34 //=============================================================================================35 36 #define one_second 1_000_000_000ul37 #define one_milisecond 1_000_000ul38 #define one_microsecond 1_000ul39 #define one_nanosecond 1ul40 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; // seconds48 this->it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds49 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 25 70 26 //============================================================================================= … … 75 31 timespec curr; 76 32 clock_gettime( CLOCK_REALTIME, &curr ); 77 return ( __cfa_time_t){ &curr };33 return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 78 34 } 79 35 80 36 void __kernel_set_timer( __cfa_time_t alarm ) { 81 itimerval val = { &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; 82 42 setitimer( ITIMER_REAL, &val, NULL ); 83 43 } … … 87 47 //============================================================================================= 88 48 89 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time) {49 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) { 90 50 this->thrd = thrd; 91 51 this->alarm = alarm; … … 96 56 } 97 57 98 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time) {58 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) { 99 59 this->proc = proc; 100 60 this->alarm = alarm; … … 111 71 } 112 72 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 122 73 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 123 verify( !n->next );74 assert( !n->next ); 124 75 if( p == this->tail ) { 125 76 this->tail = &n->next; … … 129 80 } 130 81 *p = n; 131 132 verify( validate( this ) );133 82 } 134 83 … … 140 89 141 90 insert_at( this, n, it ); 142 143 verify( validate( this ) );144 91 } 145 92 … … 153 100 head->next = NULL; 154 101 } 155 verify( validate( this ) );156 102 return head; 157 103 } … … 159 105 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 160 106 verify( it ); 161 verify( (*it) == n );107 verify( (*it)->next == n ); 162 108 163 (*it) = n->next;109 (*it)->next = n->next; 164 110 if( !n-> next ) { 165 111 this->tail = it; 166 112 } 167 113 n->next = NULL; 168 169 verify( validate( this ) );170 114 } 171 115 172 116 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 173 117 alarm_node_t ** it = &this->head; 174 while( (*it) && (*it) != n ) {118 while( (*it) && (*it)->next != n ) { 175 119 it = &(*it)->next; 176 120 } 177 121 178 verify( validate( this ) );179 180 122 if( *it ) { remove_at( this, n, it ); } 181 182 verify( validate( this ) );183 123 } 184 124 185 125 void register_self( alarm_node_t * this ) { 186 alarm_list_t * alarms = &event_kernel->alarms;187 188 126 disable_interrupts(); 189 lock( &event_kernel->lock DEBUG_CTX2 ); 127 assert( !systemProcessor->pending_alarm ); 128 lock( &systemProcessor->alarm_lock ); 190 129 { 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() ); 130 insert( &systemProcessor->alarms, this ); 131 if( systemProcessor->pending_alarm ) { 132 tick_preemption(); 197 133 } 198 134 } 199 unlock( & event_kernel->lock );135 unlock( &systemProcessor->alarm_lock ); 200 136 this->set = true; 201 enable_interrupts( DEBUG_CTX);137 enable_interrupts(); 202 138 } 203 139 204 140 void unregister_self( alarm_node_t * this ) { 205 141 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 ); 142 lock( &systemProcessor->alarm_lock ); 143 remove( &systemProcessor->alarms, this ); 144 unlock( &systemProcessor->alarm_lock ); 145 disable_interrupts(); 213 146 this->set = false; 214 147 }
Note:
See TracChangeset
for help on using the changeset viewer.