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

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 b72d4ed was c5ac6d5, checked in by Thierry Delisle <tdelisle@…>, 8 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.