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/signal.c

    r7b13aeb rc81ebf9  
     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 TracChangeset for help on using the changeset viewer.