source: src/libcfa/concurrency/alarm.c@ 579263a

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 579263a was 4aa2fb2, checked in by Thierry Delisle <tdelisle@…>, 8 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.