Ignore:
Timestamp:
Jul 19, 2017, 11:49:33 AM (8 years ago)
Author:
Aaron Moss <a3moss@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/alarm.c

    rfea3faa rb826e6b  
    1616
    1717extern "C" {
     18#include <errno.h>
     19#include <stdio.h>
     20#include <string.h>
    1821#include <time.h>
     22#include <unistd.h>
    1923#include <sys/time.h>
    2024}
     25
     26#include "libhdr.h"
    2127
    2228#include "alarm.h"
     
    2531
    2632//=============================================================================================
     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
     43void ?{}( __cfa_time_t * this ) { this->val = 0; }
     44void ?{}( __cfa_time_t * this, zero_t zero ) { this->val = 0; }
     45
     46void ?{}( 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
     54void ?{}( __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//=============================================================================================
    2771// Clock logic
    2872//=============================================================================================
     
    3175        timespec curr;
    3276        clock_gettime( CLOCK_REALTIME, &curr );
    33         return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
     77        return (__cfa_time_t){ &curr };
    3478}
    3579
    3680void __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 };
    4282        setitimer( ITIMER_REAL, &val, NULL );
    4383}
     
    4787//=============================================================================================
    4888
    49 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
     89void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) {
    5090        this->thrd = thrd;
    5191        this->alarm = alarm;
     
    5696}
    5797
    58 void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
     98void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) {
    5999        this->proc = proc;
    60100        this->alarm = alarm;
     
    71111}
    72112
     113LIB_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
    73122static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    74         assert( !n->next );
     123        verify( !n->next );
    75124        if( p == this->tail ) {
    76125                this->tail = &n->next;
     
    80129        }
    81130        *p = n;
     131
     132        verify( validate( this ) );
    82133}
    83134
     
    89140
    90141        insert_at( this, n, it );
     142
     143        verify( validate( this ) );
    91144}
    92145
     
    100153                head->next = NULL;
    101154        }
     155        verify( validate( this ) );
    102156        return head;
    103157}
     
    105159static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    106160        verify( it );
    107         verify( (*it)->next == n );
    108 
    109         (*it)->next = n->next;
     161        verify( (*it) == n );
     162
     163        (*it) = n->next;
    110164        if( !n-> next ) {
    111165                this->tail = it;
    112166        }
    113167        n->next = NULL;
     168
     169        verify( validate( this ) );
    114170}
    115171
    116172static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    117173        alarm_node_t ** it = &this->head;
    118         while( (*it) && (*it)->next != n ) {
     174        while( (*it) && (*it) != n ) {
    119175                it = &(*it)->next;
    120176        }
    121177
     178        verify( validate( this ) );
     179
    122180        if( *it ) { remove_at( this, n, it ); }
     181
     182        verify( validate( this ) );
    123183}
    124184
    125185void register_self( alarm_node_t * this ) {
     186        alarm_list_t * alarms = &event_kernel->alarms;
     187
    126188        disable_interrupts();
    127         assert( !systemProcessor->pending_alarm );
    128         lock( &systemProcessor->alarm_lock );
     189        lock( &event_kernel->lock DEBUG_CTX2 );
    129190        {
    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() );
    133197                }
    134198        }
    135         unlock( &systemProcessor->alarm_lock );
     199        unlock( &event_kernel->lock );
    136200        this->set = true;
    137         enable_interrupts();
     201        enable_interrupts( DEBUG_CTX );
    138202}
    139203
    140204void unregister_self( alarm_node_t * this ) {
    141205        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 );
    146213        this->set = false;
    147214}
Note: See TracChangeset for help on using the changeset viewer.