Ignore:
File:
1 edited

Legend:

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

    r4aeaee5 re0c235c  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 17 16:11:35 2020
    13 // Update Count     : 75
     12// Last Modified On : Sun Jan  5 08:41:36 2020
     13// Update Count     : 69
    1414//
    1515
    1616#define __cforall_thread__
    1717
     18extern "C" {
    1819#include <errno.h>
    1920#include <stdio.h>
     21#include <string.h>
    2022#include <unistd.h>
    21 #include <string.h>
    2223#include <sys/time.h>
     24}
    2325
    2426#include "alarm.hfa"
    25 #include "kernel/fwd.hfa"
     27#include "kernel_private.hfa"
    2628#include "preemption.hfa"
    2729
     
    4547//=============================================================================================
    4648
    47 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period) with( this ) {
     49void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period ) with( this ) {
    4850        this.thrd = thrd;
    4951        this.alarm = alarm;
    5052        this.period = period;
     53        next = 0;
    5154        set = false;
    52         type = User;
     55        kernel_alarm = false;
    5356}
    5457
    55 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period ) with( this ) {
     58void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period ) with( this ) {
    5659        this.proc = proc;
    5760        this.alarm = alarm;
    5861        this.period = period;
     62        next = 0;
    5963        set = false;
    60         type = Kernel;
    61 }
    62 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period ) with( this ) {
    63         this.alarm = alarm;
    64         this.period = period;
    65         this.callback = callback;
    66         set = false;
    67         type = Callback;
     64        kernel_alarm = true;
    6865}
    6966
     
    7471}
    7572
    76 void insert( alarm_list_t * this, alarm_node_t * n ) {
    77         alarm_node_t * it = & (*this)`first;
    78         while( it && (n->alarm > it->alarm) ) {
    79                 it = & (*it)`next;
    80         }
    81         if ( it ) {
    82                 insert_before( *it, *n );
    83         } else {
    84                 insert_last(*this, *n);
     73#if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))
     74bool validate( alarm_list_t * this ) {
     75        alarm_node_t ** it = &this->head;
     76        while( (*it) ) {
     77                it = &(*it)->next;
    8578        }
    8679
    87         verify( validate( *this ) );
     80        return it == this->tail;
     81}
     82#endif
     83
     84static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
     85        verify( !n->next );
     86        if( p == this->tail ) {
     87                this->tail = &n->next;
     88        }
     89        else {
     90                n->next = *p;
     91        }
     92        *p = n;
     93
     94        verify( validate( this ) );
     95}
     96
     97void insert( alarm_list_t * this, alarm_node_t * n ) {
     98        alarm_node_t ** it = &this->head;
     99        while( (*it) && (n->alarm > (*it)->alarm) ) {
     100                it = &(*it)->next;
     101        }
     102
     103        insert_at( this, n, it );
     104
     105        verify( validate( this ) );
    88106}
    89107
    90108alarm_node_t * pop( alarm_list_t * this ) {
    91         verify( validate( *this ) );
    92         alarm_node_t * head = & (*this)`first;
     109        alarm_node_t * head = this->head;
    93110        if( head ) {
    94                 remove(*head);
     111                this->head = head->next;
     112                if( !head->next ) {
     113                        this->tail = &this->head;
     114                }
     115                head->next = 0p;
    95116        }
    96         verify( validate( *this ) );
     117        verify( validate( this ) );
    97118        return head;
    98119}
    99120
     121static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
     122        verify( it );
     123        verify( (*it) == n );
     124
     125        (*it) = n->next;
     126        if( !n-> next ) {
     127                this->tail = it;
     128        }
     129        n->next = 0p;
     130
     131        verify( validate( this ) );
     132}
     133
     134static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
     135        alarm_node_t ** it = &this->head;
     136        while( (*it) && (*it) != n ) {
     137                it = &(*it)->next;
     138        }
     139
     140        verify( validate( this ) );
     141
     142        if( *it ) { remove_at( this, n, it ); }
     143
     144        verify( validate( this ) );
     145}
     146
    100147void register_self( alarm_node_t * this ) {
    101         alarm_list_t & alarms = event_kernel->alarms;
     148        alarm_list_t * alarms = &event_kernel->alarms;
    102149
    103150        disable_interrupts();
     
    105152        {
    106153                verify( validate( alarms ) );
    107                 bool first = ! & alarms`first;
     154                bool first = !alarms->head;
    108155
    109                 insert( &alarms, this );
     156                insert( alarms, this );
    110157                if( first ) {
    111                         __kernel_set_timer( alarms`first.alarm - __kernel_get_time() );
     158                        __kernel_set_timer( alarms->head->alarm - __kernel_get_time() );
    112159                }
    113160        }
     
    121168        lock( event_kernel->lock __cfaabi_dbg_ctx2 );
    122169        {
    123                 verify( validate( event_kernel->alarms ) );
    124                 remove( *this );
     170                verify( validate( &event_kernel->alarms ) );
     171                remove( &event_kernel->alarms, this );
    125172        }
    126173        unlock( event_kernel->lock );
     
    129176}
    130177
    131 //=============================================================================================
    132 // Utilities
    133 //=============================================================================================
    134 
    135 void sleep( Duration duration ) {
    136         alarm_node_t node = { active_thread(), __kernel_get_time() + duration, 0`s };
    137 
    138         register_self( &node );
    139         park();
    140 
    141         /* paranoid */ verify( !node.set );
    142         /* paranoid */ verify( & node`next == 0p );
    143         /* paranoid */ verify( & node`prev == 0p );
    144 }
    145 
    146178// Local Variables: //
    147179// mode: c //
Note: See TracChangeset for help on using the changeset viewer.