Ignore:
Timestamp:
Jun 6, 2017, 11:45:13 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
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
Message:

More work done on preemption in cforall, next step disabling interrupts at the correct places

File:
1 edited

Legend:

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

    r7b13aeb rc81ebf9  
    1515//
    1616
     17extern "C" {
     18#include <time.h>
     19#include <sys/time.h>
     20}
     21
    1722#include "alarm.h"
    1823#include "kernel_private.h"
     24#include "preemption.h"
    1925
    20 static void register_self( alarm_node_t * this ) {
    21         lock( &systemProcessor->alarm_lock );
    22         insert( &systemProcessor->alarms, this );
    23         unlock( &systemProcessor->alarm_lock );
     26//=============================================================================================
     27// Clock logic
     28//=============================================================================================
     29
     30__cfa_time_t __kernel_get_time() {
     31        timespec curr;
     32        clock_gettime( CLOCK_REALTIME, &curr );
     33        return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    2434}
    2535
    26 void ?{}( alarm_node_t * this, thread_desc * thrd, cfa_time_t alarm, cfa_time_t period = 0 ) {
     36void __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;
     42        setitimer( ITIMER_REAL, &val, NULL );
     43}
     44
     45//=============================================================================================
     46// Alarm logic
     47//=============================================================================================
     48
     49void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
    2750        this->thrd = thrd;
    2851        this->alarm = alarm;
    2952        this->period = period;
    3053        this->next = 0;
    31 
    32         register_self( this );
     54        this->set = false;
     55        this->kernel_alarm = false;
    3356}
    3457
    35 void ?{}( alarm_node_t * this, processor   * proc, cfa_time_t alarm, cfa_time_t period = 0 ) {
     58void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
    3659        this->proc = proc;
    3760        this->alarm = alarm;
    3861        this->period = period;
    3962        this->next = 0;
     63        this->set = false;
     64        this->kernel_alarm = true;
     65}
    4066
    41         register_self( this );
     67void ^?{}( alarm_node_t * this ) {
     68        if( this->set ) {
     69                unregister_self( this );
     70        }
    4271}
    4372
     
    6291}
    6392
    64 void pop( alarm_list_t * this ) {
     93alarm_node_t * pop( alarm_list_t * this ) {
    6594        alarm_node_t * head = this->head;
    6695        if( head ) {
     
    73102        return head;
    74103}
     104
     105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
     106        assert( it );
     107        assert( (*it)->next == n );
     108
     109        (*it)->next = n->next;
     110        if( !n-> next ) {
     111                this->tail = it;
     112        }
     113        n->next = NULL;
     114}
     115
     116static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
     117        alarm_node_t ** it = &this->head;
     118        while( (*it) && (*it)->next != n ) {
     119                it = &(*it)->next;
     120        }
     121
     122        if( *it ) { remove_at( this, n, it ); }
     123}
     124
     125void register_self( alarm_node_t * this ) {
     126        disable_interrupts();
     127        assert( !systemProcessor->pending_alarm );
     128        lock( &systemProcessor->alarm_lock );
     129        {
     130                insert( &systemProcessor->alarms, this );
     131                if( systemProcessor->pending_alarm ) {
     132                        tick_preemption();
     133                }
     134        }
     135        unlock( &systemProcessor->alarm_lock );
     136        this->set = true;
     137        enable_interrupts();
     138}
     139
     140void unregister_self( alarm_node_t * this ) {
     141        disable_interrupts();
     142        lock( &systemProcessor->alarm_lock );
     143        remove( &systemProcessor->alarms, this );
     144        unlock( &systemProcessor->alarm_lock );
     145        disable_interrupts();
     146        this->set = false;
     147}
Note: See TracChangeset for help on using the changeset viewer.