source: src/libcfa/concurrency/preemption.c @ c5ac6d5

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 c5ac6d5 was c5ac6d5, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Rename signal.c to preemption.c and added missing lrt

  • Property mode set to 100644
File size: 3.5 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// signal.c --
9//
10// Author           : Thierry Delisle
11// Created On       : Mon Jun 5 14:20:42 2017
12// Last Modified By : Thierry Delisle
13// Last Modified On : --
14// Update Count     : 0
15//
16
17#include "preemption.h"
18
19extern "C" {
20#include <signal.h>
21}
22
23#define __CFA_DEFAULT_PREEMPTION__ 10
24
25__attribute__((weak)) unsigned int default_preemption() {
26        return __CFA_DEFAULT_PREEMPTION__;
27}
28
29static void preempt( processor   * this );
30static void timeout( thread_desc * this );
31
32//=============================================================================================
33// Kernel Preemption logic
34//=============================================================================================
35
36void kernel_start_preemption() {
37
38}
39
40void tick_preemption() {
41        alarm_list_t * alarms = &systemProcessor->alarms;
42        __cfa_time_t currtime = __kernel_get_time();
43        while( alarms->head && alarms->head->alarm < currtime ) {
44                alarm_node_t * node = pop(alarms);
45                if( node->kernel_alarm ) {
46                        preempt( node->proc );
47                }
48                else {
49                        timeout( node->thrd );
50                }
51
52                if( node->period > 0 ) {
53                        node->alarm += node->period;
54                        insert( alarms, node );
55                }
56                else {
57                        node->set = false;
58                }
59        }
60
61        if( alarms->head ) {
62                __kernel_set_timer( alarms->head->alarm - currtime );
63        }
64}
65
66void update_preemption( processor * this, __cfa_time_t duration ) {
67        //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
68        alarm_node_t * alarm = this->preemption_alarm;
69
70        // Alarms need to be enabled
71        if ( duration > 0 && !alarm->set ) {
72                alarm->alarm = __kernel_get_time() + duration;
73                alarm->period = duration;
74                register_self( alarm );
75        }
76        // Zero duraction but alarm is set
77        else if ( duration == 0 && alarm->set ) {
78                unregister_self( alarm );
79                alarm->alarm = 0;
80                alarm->period = 0;
81        }
82        // If alarm is different from previous, change it
83        else if ( duration > 0 && alarm->period != duration ) {
84                unregister_self( alarm );
85                alarm->alarm = __kernel_get_time() + duration;
86                alarm->period = duration;
87                register_self( alarm );
88        }
89}
90
91void ?{}( preemption_scope * this, processor * proc ) {
92        (&this->alarm){ proc };
93        this->proc = proc;
94        this->proc->preemption_alarm = &this->alarm;
95        update_preemption( this->proc, this->proc->preemption );
96}
97
98void ^?{}( preemption_scope * this ) {
99        update_preemption( this->proc, 0 );
100}
101
102//=============================================================================================
103// Kernel Signal logic
104//=============================================================================================
105
106static inline bool preemption_ready() {
107        return this_processor->disable_preempt_count == 0;
108}
109
110static inline void defer_ctxSwitch() {
111        this_processor->pending_preemption = true;
112}
113
114static inline void defer_alarm() {
115        systemProcessor->pending_alarm = true;
116}
117
118void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
119        if( preemption_ready() ) {
120                ScheduleInternal( this_processor->current_thread );
121        }
122        else {
123                defer_ctxSwitch();
124        }
125}
126
127void sigHandler_alarm( __attribute__((unused)) int sig ) {
128        if( try_lock( &systemProcessor->alarm_lock ) ) {
129                tick_preemption();
130                unlock( &systemProcessor->alarm_lock );
131        }
132        else {
133                defer_alarm();
134        }
135}
136
137static void preempt( processor * this ) {
138        pthread_kill( this->kernel_thread, SIGUSR1 );
139}
140
141static void timeout( thread_desc * this ) {
142        //TODO : implement waking threads
143}
Note: See TracBrowser for help on using the repository browser.