source: src/libcfa/concurrency/alarm.c @ fda8168

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since fda8168 was 4aa2fb2, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Added verify macro for asserts only present in debug

  • Property mode set to 100644
File size: 3.6 KB
Line 
1//                              -*- Mode: CFA -*-
2//
3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
4//
5// The contents of this file are covered under the licence agreement in the
6// file "LICENCE" distributed with Cforall.
7//
8// alarm.c --
9//
10// Author           : Thierry Delisle
11// Created On       : Fri Jun 2 11:31:25 2017
12// Last Modified By : Thierry Delisle
13// Last Modified On : --
14// Update Count     : 0
15//
16
17extern "C" {
18#include <time.h>
19#include <sys/time.h>
20}
21
22#include "alarm.h"
23#include "kernel_private.h"
24#include "preemption.h"
25
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;
34}
35
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 ) {
50        this->thrd = thrd;
51        this->alarm = alarm;
52        this->period = period;
53        this->next = 0;
54        this->set = false;
55        this->kernel_alarm = false;
56}
57
58void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
59        this->proc = proc;
60        this->alarm = alarm;
61        this->period = period;
62        this->next = 0;
63        this->set = false;
64        this->kernel_alarm = true;
65}
66
67void ^?{}( alarm_node_t * this ) {
68        if( this->set ) {
69                unregister_self( this );
70        }
71}
72
73static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
74        assert( !n->next );
75        if( p == this->tail ) {
76                this->tail = &n->next;
77        }
78        else {
79                n->next = *p;
80        }
81        *p = n;
82}
83
84void insert( alarm_list_t * this, alarm_node_t * n ) {
85        alarm_node_t ** it = &this->head;
86        while( (*it) && (n->alarm > (*it)->alarm) ) {
87                it = &(*it)->next;
88        }
89
90        insert_at( this, n, it );
91}
92
93alarm_node_t * pop( alarm_list_t * this ) {
94        alarm_node_t * head = this->head;
95        if( head ) {
96                this->head = head->next;
97                if( !head->next ) {
98                        this->tail = &this->head;
99                }
100                head->next = NULL;
101        }
102        return head;
103}
104
105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
106        verify( it );
107        verify( (*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 TracBrowser for help on using the repository browser.