Changes in / [1a18423:e9a3b20b]


Ignore:
Location:
src
Files:
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/alarm.c

    r1a18423 re9a3b20b  
    1616
    1717extern "C" {
    18 #include <errno.h>
    19 #include <stdio.h>
    20 #include <string.h>
    2118#include <time.h>
    22 #include <unistd.h>
    2319#include <sys/time.h>
    2420}
     
    2622#include "alarm.h"
    2723#include "kernel_private.h"
    28 #include "libhdr.h"
    2924#include "preemption.h"
    3025
     
    3631        timespec curr;
    3732        clock_gettime( CLOCK_REALTIME, &curr );
    38         __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    39         LIB_DEBUG_DO(
    40                 char text[256];
    41                 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : current time is %lu\n", curr_time );
    42                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    43         );
    44         return curr_time;
     33        return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    4534}
    4635
    4736void __kernel_set_timer( __cfa_time_t alarm ) {
    48 
    49         LIB_DEBUG_DO(
    50                 char text[256];
    51                 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : set timer to %lu\n", (__cfa_time_t)alarm );
    52                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    53         );
    54 
    5537        itimerval val;
    5638        val.it_value.tv_sec = alarm / TIMEGRAN;                 // seconds
     
    8971}
    9072
    91 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {
    92         alarm_node_t ** it = &this->head;
    93         while( (*it) ) {
    94                 it = &(*it)->next;
    95         }
    96 
    97         return it == this->tail;
    98 })
    99 
    10073static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    101         verify( !n->next );
     74        assert( !n->next );
    10275        if( p == this->tail ) {
    10376                this->tail = &n->next;
     
    10780        }
    10881        *p = n;
    109 
    110         verify( validate( this ) );
    11182}
    11283
     
    11889
    11990        insert_at( this, n, it );
    120 
    121         verify( validate( this ) );
    12291}
    12392
     
    131100                head->next = NULL;
    132101        }
    133         verify( validate( this ) );
    134102        return head;
    135103}
     
    137105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    138106        verify( it );
    139         verify( (*it) == n );
     107        verify( (*it)->next == n );
    140108
    141         (*it) = n->next;
     109        (*it)->next = n->next;
    142110        if( !n-> next ) {
    143111                this->tail = it;
    144112        }
    145113        n->next = NULL;
    146 
    147         verify( validate( this ) );
    148114}
    149115
    150116static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    151117        alarm_node_t ** it = &this->head;
    152         while( (*it) && (*it) != n ) {
     118        while( (*it) && (*it)->next != n ) {
    153119                it = &(*it)->next;
    154120        }
    155121
    156         verify( validate( this ) );
    157 
    158122        if( *it ) { remove_at( this, n, it ); }
    159 
    160         verify( validate( this ) );
    161123}
    162124
    163125void register_self( alarm_node_t * this ) {
    164126        disable_interrupts();
    165         verify( !systemProcessor->pending_alarm );
     127        assert( !systemProcessor->pending_alarm );
    166128        lock( &systemProcessor->alarm_lock );
    167129        {
    168                 verify( validate( &systemProcessor->alarms ) );
    169                 bool first = !systemProcessor->alarms.head;
    170 
    171130                insert( &systemProcessor->alarms, this );
    172131                if( systemProcessor->pending_alarm ) {
    173132                        tick_preemption();
    174133                }
    175                 if( first ) {
    176                         __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
    177                 }
    178134        }
    179135        unlock( &systemProcessor->alarm_lock );
    180136        this->set = true;
    181         enable_interrupts( __PRETTY_FUNCTION__ );
     137        enable_interrupts();
    182138}
    183139
    184140void unregister_self( alarm_node_t * this ) {
    185         LIB_DEBUG_DO(
    186                 char text[256];
    187                 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : unregister %p start\n", this );
    188                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    189         );
    190141        disable_interrupts();
    191142        lock( &systemProcessor->alarm_lock );
    192         {
    193                 verify( validate( &systemProcessor->alarms ) );
    194                 remove( &systemProcessor->alarms, this );
    195         }
     143        remove( &systemProcessor->alarms, this );
    196144        unlock( &systemProcessor->alarm_lock );
    197145        disable_interrupts();
    198146        this->set = false;
    199         LIB_DEBUG_DO(
    200                 len = snprintf( text, 256, "Kernel : unregister %p end\n", this );
    201                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    202         );
    203147}
  • src/libcfa/concurrency/coroutine.c

    r1a18423 re9a3b20b  
    3232#include "invoke.h"
    3333
    34 extern volatile thread_local processor * this_processor;
     34extern thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/invoke.c

    r1a18423 re9a3b20b  
    3030extern void __suspend_internal(void);
    3131extern void __leave_monitor_desc( struct monitor_desc * this );
    32 extern void disable_interrupts();
    33 extern void enable_interrupts( const char * );
    3432
    3533void CtxInvokeCoroutine(
     
    6967      struct monitor_desc* mon = &thrd->mon;
    7068      cor->state = Active;
    71       enable_interrupts( __PRETTY_FUNCTION__ );
    7269
    7370      // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
    7471      main( this );
    7572
    76       disable_interrupts();
    7773      __leave_monitor_desc( mon );
    7874
  • src/libcfa/concurrency/kernel

    r1a18423 re9a3b20b  
    9090        unsigned int preemption;
    9191
     92        unsigned short disable_preempt_count;
     93
    9294        bool pending_preemption;
    93 
    94         char * last_enable;
    9595};
    9696
  • src/libcfa/concurrency/kernel.c

    r1a18423 re9a3b20b  
    5959// Global state
    6060
    61 volatile thread_local processor * this_processor;
    62 volatile thread_local unsigned short disable_preempt_count;
     61thread_local processor * this_processor;
    6362
    6463coroutine_desc * this_coroutine(void) {
     
    143142        this->preemption_alarm = NULL;
    144143        this->preemption = default_preemption();
     144        this->disable_preempt_count = 1;                //Start with interrupts disabled
    145145        this->pending_preemption = false;
    146146
     
    154154        (&this->terminated){};
    155155        this->is_terminated = false;
    156         this->preemption_alarm = NULL;
    157         this->preemption = default_preemption();
     156        this->disable_preempt_count = 0;
    158157        this->pending_preemption = false;
    159         this->kernel_thread = pthread_self();
    160158
    161159        this->runner = runner;
    162         LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
     160        LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
    163161        runner{ this };
    164162}
    165 
    166 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    167163
    168164void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    172168
    173169        (&this->proc){ cltr, runner };
    174 
    175         verify( validate( &this->alarms ) );
    176170}
    177171
     
    215209                        if(readyThread)
    216210                        {
    217                                 verify( disable_preempt_count > 0 );
    218 
    219211                                runThread(this, readyThread);
    220 
    221                                 verify( disable_preempt_count > 0 );
    222212
    223213                                //Some actions need to be taken from the kernel
     
    299289        processor * proc = (processor *) arg;
    300290        this_processor = proc;
    301         disable_preempt_count = 1;
    302291        // SKULLDUGGERY: We want to create a context for the processor coroutine
    303292        // which is needed for the 2-step context switch. However, there is no reason
     
    333322void start(processor * this) {
    334323        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    335 
    336         // SIGALRM must only be caught by the system processor
    337         sigset_t old_mask;
    338         bool is_system_proc = this_processor == &systemProcessor->proc;
    339         if ( is_system_proc ) {
    340                 // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the
    341                 // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user
    342                 // processor, and toggle back (below) previous signal mask of the system processor.
    343 
    344                 sigset_t new_mask;
    345                 sigemptyset( &new_mask );
    346                 sigemptyset( &old_mask );
    347                 sigaddset( &new_mask, SIGALRM );
    348 
    349                 if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) {
    350                         abortf( "internal error, sigprocmask" );
    351                 }
    352 
    353                 assert( ! sigismember( &old_mask, SIGALRM ) );
    354         }
    355 
     324       
    356325        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    357 
    358         // Toggle back previous signal mask of system processor.
    359         if ( is_system_proc ) {
    360                 if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {
    361                         abortf( "internal error, sigprocmask" );
    362                 } // if
    363         } // if
    364326
    365327        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
     
    385347}
    386348
    387 void BlockInternal() {
    388         disable_interrupts();
    389         verify( disable_preempt_count > 0 );
     349void ScheduleInternal() {
    390350        suspend();
    391         verify( disable_preempt_count > 0 );
    392         enable_interrupts( __PRETTY_FUNCTION__ );
    393 }
    394 
    395 void BlockInternal( spinlock * lock ) {
    396         disable_interrupts();
     351}
     352
     353void ScheduleInternal( spinlock * lock ) {
    397354        this_processor->finish.action_code = Release;
    398355        this_processor->finish.lock = lock;
    399 
    400         verify( disable_preempt_count > 0 );
    401356        suspend();
    402         verify( disable_preempt_count > 0 );
    403 
    404         enable_interrupts( __PRETTY_FUNCTION__ );
    405 }
    406 
    407 void BlockInternal( thread_desc * thrd ) {
    408         disable_interrupts();
     357}
     358
     359void ScheduleInternal( thread_desc * thrd ) {
    409360        this_processor->finish.action_code = Schedule;
    410361        this_processor->finish.thrd = thrd;
    411 
    412         verify( disable_preempt_count > 0 );
    413362        suspend();
    414         verify( disable_preempt_count > 0 );
    415 
    416         enable_interrupts( __PRETTY_FUNCTION__ );
    417 }
    418 
    419 void BlockInternal( spinlock * lock, thread_desc * thrd ) {
    420         disable_interrupts();
     363}
     364
     365void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
    421366        this_processor->finish.action_code = Release_Schedule;
    422367        this_processor->finish.lock = lock;
    423368        this_processor->finish.thrd = thrd;
    424 
    425         verify( disable_preempt_count > 0 );
    426369        suspend();
    427         verify( disable_preempt_count > 0 );
    428 
    429         enable_interrupts( __PRETTY_FUNCTION__ );
    430 }
    431 
    432 void BlockInternal(spinlock ** locks, unsigned short count) {
    433         disable_interrupts();
     370}
     371
     372void ScheduleInternal(spinlock ** locks, unsigned short count) {
    434373        this_processor->finish.action_code = Release_Multi;
    435374        this_processor->finish.locks = locks;
    436375        this_processor->finish.lock_count = count;
    437 
    438         verify( disable_preempt_count > 0 );
    439376        suspend();
    440         verify( disable_preempt_count > 0 );
    441 
    442         enable_interrupts( __PRETTY_FUNCTION__ );
    443 }
    444 
    445 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    446         disable_interrupts();
     377}
     378
     379void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    447380        this_processor->finish.action_code = Release_Multi_Schedule;
    448381        this_processor->finish.locks = locks;
     
    450383        this_processor->finish.thrds = thrds;
    451384        this_processor->finish.thrd_count = thrd_count;
    452 
    453         verify( disable_preempt_count > 0 );
    454385        suspend();
    455         verify( disable_preempt_count > 0 );
    456 
    457         enable_interrupts( __PRETTY_FUNCTION__ );
    458386}
    459387
     
    475403        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    476404
     405        // Enable preemption
     406        kernel_start_preemption();
     407
    477408        // Initialize the system cluster
    478409        systemCluster = (cluster *)&systemCluster_storage;
     
    494425        this_processor->current_thread = mainThread;
    495426        this_processor->current_coroutine = &mainThread->cor;
    496         disable_preempt_count = 1;
    497 
    498         // Enable preemption
    499         kernel_start_preemption();
    500427
    501428        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
     
    508435        // THE SYSTEM IS NOW COMPLETELY RUNNING
    509436        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
    510 
    511         enable_interrupts( __PRETTY_FUNCTION__ );
    512437}
    513438
    514439void kernel_shutdown(void) {
    515440        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
    516 
    517         disable_interrupts();
    518441
    519442        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    524447
    525448        // THE SYSTEM IS NOW COMPLETELY STOPPED
    526 
    527         // Disable preemption
    528         kernel_stop_preemption();
    529449
    530450        // Destroy the system processor and its context in reverse order of construction
     
    630550        if( !this->cond ) {
    631551                append( &this->blocked, this_thread() );
    632                 BlockInternal( &this->lock );
    633         }
    634         else {
    635                 unlock( &this->lock );
    636         }
     552                ScheduleInternal( &this->lock );
     553                lock( &this->lock );
     554        }
     555        unlock( &this->lock );
    637556}
    638557
     
    642561                this->cond = true;
    643562
    644                 disable_interrupts();
    645563                thread_desc * it;
    646564                while( it = pop_head( &this->blocked) ) {
    647565                        ScheduleThread( it );
    648566                }
    649                 enable_interrupts( __PRETTY_FUNCTION__ );
    650567        }
    651568        unlock( &this->lock );
  • src/libcfa/concurrency/kernel_private.h

    r1a18423 re9a3b20b  
    3030thread_desc * nextThread(cluster * this);
    3131
    32 void BlockInternal(void);
    33 void BlockInternal(spinlock * lock);
    34 void BlockInternal(thread_desc * thrd);
    35 void BlockInternal(spinlock * lock, thread_desc * thrd);
    36 void BlockInternal(spinlock ** locks, unsigned short count);
    37 void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     32void ScheduleInternal(void);
     33void ScheduleInternal(spinlock * lock);
     34void ScheduleInternal(thread_desc * thrd);
     35void ScheduleInternal(spinlock * lock, thread_desc * thrd);
     36void ScheduleInternal(spinlock ** locks, unsigned short count);
     37void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
    3838
    3939//-----------------------------------------------------------------------------
     
    6060extern cluster * systemCluster;
    6161extern system_proc_t * systemProcessor;
    62 extern volatile thread_local processor * this_processor;
    63 extern volatile thread_local unsigned short disable_preempt_count;
     62extern thread_local processor * this_processor;
    6463
    65 extern "C" {
    66         void disable_interrupts();
    67         void enable_interrupts_noRF();
    68         void enable_interrupts( const char * );
     64static inline void disable_interrupts() {
     65        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST );
     66        assert( prev != (unsigned short) -1 );
     67}
     68
     69static inline void enable_interrupts_noRF() {
     70        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     71        verify( prev != (unsigned short) 0 );
     72}
     73
     74static inline void enable_interrupts() {
     75        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     76        verify( prev != (unsigned short) 0 );
     77        if( prev == 1 && this_processor->pending_preemption ) {
     78                ScheduleInternal( this_processor->current_thread );
     79                this_processor->pending_preemption = false;
     80        }
    6981}
    7082
  • src/libcfa/concurrency/monitor.c

    r1a18423 re9a3b20b  
    6363                        append( &this->entry_queue, thrd );
    6464                        LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    65                         BlockInternal( &this->lock );
    66 
    67                         //BlockInternal will unlock spinlock, no need to unlock ourselves
     65                        ScheduleInternal( &this->lock );
     66
     67                        //ScheduleInternal will unlock spinlock, no need to unlock ourselves
    6868                        return;
    6969                }
     
    170170        unsigned short count = this->monitor_count;
    171171        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    172         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
     172        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    173173
    174174        LIB_DEBUG_PRINT_SAFE("count %i\n", count);
     
    208208
    209209        // Everything is ready to go to sleep
    210         BlockInternal( locks, count, threads, thread_count );
     210        ScheduleInternal( locks, count, threads, thread_count );
    211211
    212212
     
    281281        unsigned short count = this->monitor_count;
    282282        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    283         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
     283        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    284284
    285285        lock_all( this->monitors, locks, count );
     
    309309
    310310        //Everything is ready to go to sleep
    311         BlockInternal( locks, count, &signallee, 1 );
     311        ScheduleInternal( locks, count, &signallee, 1 );
    312312
    313313
     
    339339        // unsigned short count = this->current_monitor_count;
    340340        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    341         // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
     341        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to ScheduleInternal
    342342
    343343        // lock_all( this->current_monitors, locks, count );
     
    348348
    349349        // // // Everything is ready to go to sleep
    350         // // BlockInternal( locks, count, threads, thread_count );
     350        // // ScheduleInternal( locks, count, threads, thread_count );
    351351
    352352
  • src/libcfa/concurrency/preemption.c

    r1a18423 re9a3b20b  
    1717#include "preemption.h"
    1818
    19 
    2019extern "C" {
    21 #include <errno.h>
    22 #define __USE_GNU
    2320#include <signal.h>
    24 #undef __USE_GNU
    25 #include <stdio.h>
    26 #include <string.h>
    27 #include <unistd.h>
    2821}
    2922
    30 #include "libhdr.h"
    31 
    32 #define __CFA_DEFAULT_PREEMPTION__ 10000
     23#define __CFA_DEFAULT_PREEMPTION__ 10
    3324
    3425__attribute__((weak)) unsigned int default_preemption() {
     
    3627}
    3728
    38 #define __CFA_SIGCXT__ ucontext_t *
    39 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt
    40 
    4129static void preempt( processor   * this );
    4230static void timeout( thread_desc * this );
    43 
    44 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
    45 void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    46 
    47 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    4831
    4932//=============================================================================================
     
    5235
    5336void kernel_start_preemption() {
    54         LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");
    55         __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO );
    56         __kernel_sigaction( SIGALRM, sigHandler_alarm    , SA_SIGINFO );
     37
    5738}
    5839
    59 void kernel_stop_preemption() {
    60         //Block all signals, we are no longer in a position to handle them
    61         sigset_t mask;
    62         sigfillset( &mask );
    63         sigprocmask( SIG_BLOCK, &mask, NULL );
    64         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");
    65 
    66         assert( !systemProcessor->alarms.head );
    67         assert( systemProcessor->alarms.tail == &systemProcessor->alarms.head );
    68 }
    69 
    70 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    71 
    7240void tick_preemption() {
    73         LIB_DEBUG_DO(
    74                 char text[256];
    75                 __attribute__((unused)) int len = snprintf( text, 256, "Ticking preemption\n" );
    76                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    77         );
    78 
    7941        alarm_list_t * alarms = &systemProcessor->alarms;
    8042        __cfa_time_t currtime = __kernel_get_time();
    8143        while( alarms->head && alarms->head->alarm < currtime ) {
    8244                alarm_node_t * node = pop(alarms);
    83                 LIB_DEBUG_DO(
    84                         len = snprintf( text, 256, "Ticking %p\n", node );
    85                         LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    86                 );
    8745                if( node->kernel_alarm ) {
    8846                        preempt( node->proc );
     
    9250                }
    9351
    94                 LIB_DEBUG_DO( assert( validate( alarms ) ) );
    95 
    9652                if( node->period > 0 ) {
    97                         node->alarm = currtime + node->period;
     53                        node->alarm += node->period;
    9854                        insert( alarms, node );
    9955                }
     
    10662                __kernel_set_timer( alarms->head->alarm - currtime );
    10763        }
    108 
    109         verify( validate( alarms ) );
    110         LIB_DEBUG_DO(
    111                 len = snprintf( text, 256, "Ticking preemption done\n" );
    112                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    113         );
    11464}
    11565
    11666void update_preemption( processor * this, __cfa_time_t duration ) {
    117         LIB_DEBUG_DO(
    118                 char text[256];
    119                 __attribute__((unused)) int len = snprintf( text, 256, "Processor : %p updating preemption to %lu\n", this, duration );
    120                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    121         );
    122 
     67        //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
    12368        alarm_node_t * alarm = this->preemption_alarm;
    124         duration *= 1000;
    12569
    12670        // Alarms need to be enabled
     
    15397
    15498void ^?{}( preemption_scope * this ) {
    155         disable_interrupts();
    156 
    15799        update_preemption( this->proc, 0 );
    158100}
     
    162104//=============================================================================================
    163105
    164 extern "C" {
    165         void disable_interrupts() {
    166                 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
    167                 verify( new_val < (unsigned short)65_000 );
    168                 verify( new_val != (unsigned short) 0 );
    169         }
    170 
    171         void enable_interrupts_noRF() {
    172                 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    173                 verify( prev != (unsigned short) 0 );
    174         }
    175 
    176         void enable_interrupts( const char * func ) {
    177                 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    178                 verify( prev != (unsigned short) 0 );
    179                 if( prev == 1 && this_processor->pending_preemption ) {
    180                         this_processor->pending_preemption = false;
    181                         LIB_DEBUG_DO(
    182                                 char text[256];
    183                                 __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch on %p\n", this_processor );
    184                                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    185                         );
    186                         BlockInternal( this_processor->current_thread );
    187                 }
    188 
    189                 this_processor->last_enable = func;
    190         }
    191 }
    192 
    193 static inline void signal_unblock( bool alarm ) {
    194         sigset_t mask;
    195         sigemptyset( &mask );
    196         sigaddset( &mask, SIGUSR1 );
    197 
    198         if( alarm ) sigaddset( &mask, SIGALRM );
    199 
    200         if ( sigprocmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {
    201             abortf( "internal error, sigprocmask" );
    202         } // if
    203 }
    204 
    205106static inline bool preemption_ready() {
    206         return disable_preempt_count == 0;
     107        return this_processor->disable_preempt_count == 0;
    207108}
    208109
     
    215116}
    216117
    217 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    218 
    219         LIB_DEBUG_DO(
    220                 char text[256];
    221                 __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]));
    222                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    223         );
    224 
    225         signal_unblock( false );
     118void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
    226119        if( preemption_ready() ) {
    227                 LIB_DEBUG_DO(
    228                         len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread %p on %p\n", this_processor->current_thread, this_processor );
    229                         LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    230                 );
    231                 BlockInternal( this_processor->current_thread );
     120                ScheduleInternal( this_processor->current_thread );
    232121        }
    233122        else {
    234                 LIB_DEBUG_DO(
    235                         len = snprintf( text, 256, "Ctx Switch IRH : Defering\n" );
    236                         LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    237                 );
    238123                defer_ctxSwitch();
    239124        }
    240125}
    241126
    242 void sigHandler_alarm( __CFA_SIGPARMS__ ) {
    243 
    244         LIB_DEBUG_DO(
    245                 char text[256];
    246                 __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]) );
    247                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    248         );
    249 
    250         signal_unblock( true );
     127void sigHandler_alarm( __attribute__((unused)) int sig ) {
    251128        if( try_lock( &systemProcessor->alarm_lock ) ) {
    252129                tick_preemption();
     
    256133                defer_alarm();
    257134        }
    258 
    259         if( preemption_ready() && this_processor->pending_preemption ) {
    260                 LIB_DEBUG_DO(
    261                         len = snprintf( text, 256, "Alarm IRH : Blocking thread\n" );
    262                         LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    263                 );
    264                 this_processor->pending_preemption = false;
    265                 BlockInternal( this_processor->current_thread );
    266         }
    267135}
    268136
    269137static void preempt( processor * this ) {
    270         LIB_DEBUG_DO(
    271                 char text[256];
    272                 __attribute__((unused)) int len = snprintf( text, 256, "Processor : signalling %p\n", this );
    273                 LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    274         );
    275 
    276         if( this != systemProcessor ) {
    277                 pthread_kill( this->kernel_thread, SIGUSR1 );
    278         }
    279         else {
    280                 defer_ctxSwitch();
    281         }
     138        pthread_kill( this->kernel_thread, SIGUSR1 );
    282139}
    283140
     
    285142        //TODO : implement waking threads
    286143}
    287 
    288 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
    289         struct sigaction act;
    290 
    291         act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
    292         sigemptyset( &act.sa_mask );
    293         sigaddset( &act.sa_mask, SIGALRM );             // disabled during signal handler
    294         sigaddset( &act.sa_mask, SIGUSR1 );
    295 
    296         act.sa_flags = flags;
    297 
    298         if ( sigaction( sig, &act, NULL ) == -1 ) {
    299                 // THE KERNEL IS NOT STARTED SO CALL NO uC++ ROUTINES!
    300                 char helpText[256];
    301                 __attribute__((unused)) int len = snprintf( helpText, 256, " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
    302                                 sig, handler, flags, errno, strerror( errno ) );
    303                 LIB_DEBUG_WRITE( STDERR_FILENO, helpText, len );
    304                 _exit( EXIT_FAILURE );
    305         } // if
    306 }
  • src/libcfa/concurrency/thread.c

    r1a18423 re9a3b20b  
    2828}
    2929
    30 extern volatile thread_local processor * this_processor;
     30extern thread_local processor * this_processor;
    3131
    3232//-----------------------------------------------------------------------------
     
    8484
    8585void yield( void ) {
    86         BlockInternal( this_processor->current_thread );
     86        ScheduleInternal( this_processor->current_thread );
    8787}
    8888
  • src/libcfa/libhdr/libdebug.h

    r1a18423 re9a3b20b  
    1919#ifdef __CFA_DEBUG__
    2020        #define LIB_DEBUG_DO(x) x
    21         #define LIB_NO_DEBUG_DO(x)
     21        #define LIB_NO_DEBUG_DO(x) ((void)0)
    2222#else
    23         #define LIB_DEBUG_DO(x)
    24         #define LIB_NO_DEBUG_DO(x) x
     23        #define LIB_DEBUG_DO(x) ((void)0)
     24        #define LIB_NO_DEBUG_DO(x) x     
    2525#endif
    2626
Note: See TracChangeset for help on using the changeset viewer.