Changes in / [7812f1d1:f73f5f4]


Ignore:
Location:
src
Files:
5 added
27 edited

Legend:

Unmodified
Added
Removed
  • src/benchmark/CorCtxSwitch.c

    r7812f1d1 rf73f5f4  
    3131
    3232        StartTime = Time();
    33         // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
    34         //      resume( this_coroutine() );
    35         //      // resume( &s );       
    36         // }
    3733        resumer( &s, NoOfTimes );
    3834        EndTime = Time();
  • src/benchmark/csv-data.c

    r7812f1d1 rf73f5f4  
    3838
    3939        StartTime = Time();
    40         // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
    41         //      resume( this_coroutine() );
    42         //      // resume( &s );
    43         // }
    4440        resumer( &s, NoOfTimes );
    4541        EndTime = Time();
  • src/libcfa/concurrency/alarm.c

    r7812f1d1 rf73f5f4  
    1616
    1717extern "C" {
     18#include <errno.h>
     19#include <stdio.h>
     20#include <string.h>
    1821#include <time.h>
     22#include <unistd.h>
    1923#include <sys/time.h>
    2024}
     25
     26#include "libhdr.h"
    2127
    2228#include "alarm.h"
     
    3137        timespec curr;
    3238        clock_gettime( CLOCK_REALTIME, &curr );
    33         return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
     39        __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
     40        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : current time is %lu\n", curr_time );
     41        return curr_time;
    3442}
    3543
    3644void __kernel_set_timer( __cfa_time_t alarm ) {
     45        LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : set timer to %lu\n", (__cfa_time_t)alarm );
    3746        itimerval val;
    3847        val.it_value.tv_sec = alarm / TIMEGRAN;                 // seconds
     
    7180}
    7281
     82LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {
     83        alarm_node_t ** it = &this->head;
     84        while( (*it) ) {
     85                it = &(*it)->next;
     86        }
     87
     88        return it == this->tail;
     89})
     90
    7391static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    74         assert( !n->next );
     92        verify( !n->next );
    7593        if( p == this->tail ) {
    7694                this->tail = &n->next;
     
    8098        }
    8199        *p = n;
     100
     101        verify( validate( this ) );
    82102}
    83103
     
    89109
    90110        insert_at( this, n, it );
     111
     112        verify( validate( this ) );
    91113}
    92114
     
    100122                head->next = NULL;
    101123        }
     124        verify( validate( this ) );
    102125        return head;
    103126}
     
    105128static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    106129        verify( it );
    107         verify( (*it)->next == n );
     130        verify( (*it) == n );
    108131
    109         (*it)->next = n->next;
     132        (*it) = n->next;
    110133        if( !n-> next ) {
    111134                this->tail = it;
    112135        }
    113136        n->next = NULL;
     137
     138        verify( validate( this ) );
    114139}
    115140
    116141static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    117142        alarm_node_t ** it = &this->head;
    118         while( (*it) && (*it)->next != n ) {
     143        while( (*it) && (*it) != n ) {
    119144                it = &(*it)->next;
    120145        }
    121146
     147        verify( validate( this ) );
     148
    122149        if( *it ) { remove_at( this, n, it ); }
     150
     151        verify( validate( this ) );
    123152}
    124153
    125154void register_self( alarm_node_t * this ) {
    126155        disable_interrupts();
    127         assert( !systemProcessor->pending_alarm );
    128         lock( &systemProcessor->alarm_lock );
     156        verify( !systemProcessor->pending_alarm );
     157        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    129158        {
     159                verify( validate( &systemProcessor->alarms ) );
     160                bool first = !systemProcessor->alarms.head;
     161
    130162                insert( &systemProcessor->alarms, this );
    131163                if( systemProcessor->pending_alarm ) {
    132164                        tick_preemption();
    133165                }
     166                if( first ) {
     167                        __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
     168                }
    134169        }
    135170        unlock( &systemProcessor->alarm_lock );
    136171        this->set = true;
    137         enable_interrupts();
     172        enable_interrupts( DEBUG_CTX );
    138173}
    139174
    140175void unregister_self( alarm_node_t * this ) {
     176        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );
    141177        disable_interrupts();
    142         lock( &systemProcessor->alarm_lock );
    143         remove( &systemProcessor->alarms, this );
     178        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     179        {
     180                verify( validate( &systemProcessor->alarms ) );
     181                remove( &systemProcessor->alarms, this );
     182        }
    144183        unlock( &systemProcessor->alarm_lock );
    145         disable_interrupts();
     184        enable_interrupts( DEBUG_CTX );
    146185        this->set = false;
     186        // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );
    147187}
  • src/libcfa/concurrency/coroutine

    r7812f1d1 rf73f5f4  
    6363
    6464// Get current coroutine
    65 coroutine_desc * this_coroutine(void);
     65extern volatile thread_local coroutine_desc * this_coroutine;
    6666
    6767// Private wrappers for context switch and stack creation
     
    7171// Suspend implementation inlined for performance
    7272static inline void suspend() {
    73         coroutine_desc * src = this_coroutine();                // optimization
     73        coroutine_desc * src = this_coroutine;          // optimization
    7474
    7575        assertf( src->last != 0,
     
    8888forall(dtype T | is_coroutine(T))
    8989static inline void resume(T * cor) {
    90         coroutine_desc * src = this_coroutine();                // optimization
     90        coroutine_desc * src = this_coroutine;          // optimization
    9191        coroutine_desc * dst = get_coroutine(cor);
    9292
     
    112112
    113113static inline void resume(coroutine_desc * dst) {
    114         coroutine_desc * src = this_coroutine();                // optimization
     114        coroutine_desc * src = this_coroutine;          // optimization
    115115
    116116        // not resuming self ?
  • src/libcfa/concurrency/coroutine.c

    r7812f1d1 rf73f5f4  
    3232#include "invoke.h"
    3333
    34 extern thread_local processor * this_processor;
     34extern volatile thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
     
    4444// Coroutine ctors and dtors
    4545void ?{}(coStack_t* this) {
    46         this->size              = 10240;        // size of stack
     46        this->size              = 65000;        // size of stack
    4747        this->storage   = NULL; // pointer to stack
    4848        this->limit             = NULL; // stack grows towards stack limit
     
    5050        this->context   = NULL; // address of cfa_context_t
    5151        this->top               = NULL; // address of top of storage
    52         this->userStack = false;       
     52        this->userStack = false;
    5353}
    5454
     
    106106
    107107        // set state of current coroutine to inactive
    108         src->state = Inactive;
     108        src->state = src->state == Halted ? Halted : Inactive;
    109109
    110110        // set new coroutine that task is executing
    111         this_processor->current_coroutine = dst;
     111        this_coroutine = dst;
    112112
    113113        // context switch to specified coroutine
     114        assert( src->stack.context );
    114115        CtxSwitch( src->stack.context, dst->stack.context );
    115         // when CtxSwitch returns we are back in the src coroutine             
     116        // when CtxSwitch returns we are back in the src coroutine
    116117
    117118        // set state of new coroutine to active
     
    131132                this->size = libCeiling( storageSize, 16 );
    132133                // use malloc/memalign because "new" raises an exception for out-of-memory
    133                
     134
    134135                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    135136                LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
  • src/libcfa/concurrency/invoke.c

    r7812f1d1 rf73f5f4  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_monitor_desc( struct monitor_desc * this );
     31extern void __leave_thread_monitor( struct thread_desc * this );
     32extern void disable_interrupts();
     33extern void enable_interrupts( DEBUG_CTX_PARAM );
    3234
    3335void CtxInvokeCoroutine(
    34       void (*main)(void *), 
    35       struct coroutine_desc *(*get_coroutine)(void *), 
     36      void (*main)(void *),
     37      struct coroutine_desc *(*get_coroutine)(void *),
    3638      void *this
    3739) {
     
    5658
    5759void CtxInvokeThread(
    58       void (*dtor)(void *), 
    59       void (*main)(void *), 
    60       struct thread_desc *(*get_thread)(void *), 
     60      void (*dtor)(void *),
     61      void (*main)(void *),
     62      struct thread_desc *(*get_thread)(void *),
    6163      void *this
    6264) {
     65      // First suspend, once the thread arrives here,
     66      // the function pointer to main can be invalidated without risk
    6367      __suspend_internal();
    6468
     69      // Fetch the thread handle from the user defined thread structure
    6570      struct thread_desc* thrd = get_thread( this );
    66       struct coroutine_desc* cor = &thrd->cor;
    67       struct monitor_desc* mon = &thrd->mon;
    68       cor->state = Active;
    6971
    70       // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
     72      // Officially start the thread by enabling preemption
     73      enable_interrupts( DEBUG_CTX );
     74
     75      // Call the main of the thread
    7176      main( this );
    7277
    73       __leave_monitor_desc( mon );
    74 
     78      // To exit a thread we must :
     79      // 1 - Mark it as halted
     80      // 2 - Leave its monitor
     81      // 3 - Disable the interupts
     82      // 4 - Final suspend
     83      // The order of these 4 operations is very important
    7584      //Final suspend, should never return
    76       __suspend_internal();
     85      __leave_thread_monitor( thrd );
    7786      abortf("Resumed dead thread");
    7887}
     
    8089
    8190void CtxStart(
    82       void (*main)(void *), 
    83       struct coroutine_desc *(*get_coroutine)(void *), 
    84       void *this, 
     91      void (*main)(void *),
     92      struct coroutine_desc *(*get_coroutine)(void *),
     93      void *this,
    8594      void (*invoke)(void *)
    8695) {
     
    108117        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    109118      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    110       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
     119      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    111120
    112121#elif defined( __x86_64__ )
     
    128137      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
    129138      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    130       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
     139      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    131140#else
    132141      #error Only __i386__ and __x86_64__ is supported for threads in cfa
  • src/libcfa/concurrency/invoke.h

    r7812f1d1 rf73f5f4  
    3131      struct spinlock {
    3232            volatile int lock;
     33            #ifdef __CFA_DEBUG__
     34                  const char * prev_name;
     35                  void* prev_thrd;
     36            #endif
    3337      };
    3438
     
    8387            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    8488            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    85             struct monitor_desc * stack_owner;        // if bulk acquiring was used we need to synchronize signals with an other monitor
    8689            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    8790      };
  • src/libcfa/concurrency/kernel

    r7812f1d1 rf73f5f4  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 bool try_lock( spinlock * );
    31 void lock( spinlock * );
    32 void unlock( spinlock * );
     30bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
     31void lock      ( spinlock * DEBUG_CTX_PARAM2 );
     32void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
     33void unlock    ( spinlock * );
    3334
    34 struct signal_once {
    35         volatile bool cond;
    36         struct spinlock lock;
    37         struct __thread_queue_t blocked;
     35struct semaphore {
     36        spinlock lock;
     37        int count;
     38        __thread_queue_t waiting;
    3839};
    3940
    40 void ?{}(signal_once * this);
    41 void ^?{}(signal_once * this);
     41void  ?{}(semaphore * this, int count = 1);
     42void ^?{}(semaphore * this);
     43void P(semaphore * this);
     44void V(semaphore * this);
    4245
    43 void wait( signal_once * );
    44 void signal( signal_once * );
    4546
    4647//-----------------------------------------------------------------------------
     
    6869        unsigned short thrd_count;
    6970};
    70 static inline void ?{}(FinishAction * this) { 
     71static inline void ?{}(FinishAction * this) {
    7172        this->action_code = No_Action;
    7273        this->thrd = NULL;
     
    7879        struct processorCtx_t * runner;
    7980        cluster * cltr;
    80         coroutine_desc * current_coroutine;
    81         thread_desc * current_thread;
    8281        pthread_t kernel_thread;
    83        
    84         signal_once terminated;
     82
     83        semaphore terminated;
    8584        volatile bool is_terminated;
    8685
     
    9089        unsigned int preemption;
    9190
    92         unsigned short disable_preempt_count;
     91        bool pending_preemption;
    9392
    94         bool pending_preemption;
     93        char * last_enable;
    9594};
    9695
  • src/libcfa/concurrency/kernel.c

    r7812f1d1 rf73f5f4  
    1515//
    1616
    17 #include "startup.h"
    18 
    19 //Start and stop routine for the kernel, declared first to make sure they run first
    20 void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    21 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    22 
    23 //Header
    24 #include "kernel_private.h"
     17#include "libhdr.h"
    2518
    2619//C Includes
     
    3528
    3629//CFA Includes
    37 #include "libhdr.h"
     30#include "kernel_private.h"
    3831#include "preemption.h"
     32#include "startup.h"
    3933
    4034//Private includes
     
    4236#include "invoke.h"
    4337
     38//Start and stop routine for the kernel, declared first to make sure they run first
     39void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     40void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     41
    4442//-----------------------------------------------------------------------------
    4543// Kernel storage
    46 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
     44#define KERNEL_STORAGE(T,X) static char X##Storage[sizeof(T)]
    4745
    4846KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
     
    5048KERNEL_STORAGE(system_proc_t, systemProcessor);
    5149KERNEL_STORAGE(thread_desc, mainThread);
    52 KERNEL_STORAGE(machine_context_t, mainThread_context);
     50KERNEL_STORAGE(machine_context_t, mainThreadCtx);
    5351
    5452cluster * systemCluster;
     
    5957// Global state
    6058
    61 thread_local processor * this_processor;
    62 
    63 coroutine_desc * this_coroutine(void) {
    64         return this_processor->current_coroutine;
    65 }
    66 
    67 thread_desc * this_thread(void) {
    68         return this_processor->current_thread;
    69 }
     59volatile thread_local processor * this_processor;
     60volatile thread_local coroutine_desc * this_coroutine;
     61volatile thread_local thread_desc * this_thread;
     62volatile thread_local unsigned short disable_preempt_count = 1;
    7063
    7164//-----------------------------------------------------------------------------
     
    9184
    9285        this->limit = (void *)(((intptr_t)this->base) - this->size);
    93         this->context = &mainThread_context_storage;
     86        this->context = &mainThreadCtxStorage;
    9487        this->top = this->base;
    9588}
     
    136129void ?{}(processor * this, cluster * cltr) {
    137130        this->cltr = cltr;
    138         this->current_coroutine = NULL;
    139         this->current_thread = NULL;
    140         (&this->terminated){};
     131        (&this->terminated){ 0 };
    141132        this->is_terminated = false;
    142133        this->preemption_alarm = NULL;
    143134        this->preemption = default_preemption();
    144         this->disable_preempt_count = 1;                //Start with interrupts disabled
    145135        this->pending_preemption = false;
    146136
     
    150140void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    151141        this->cltr = cltr;
    152         this->current_coroutine = NULL;
    153         this->current_thread = NULL;
    154         (&this->terminated){};
     142        (&this->terminated){ 0 };
    155143        this->is_terminated = false;
    156         this->disable_preempt_count = 0;
     144        this->preemption_alarm = NULL;
     145        this->preemption = default_preemption();
    157146        this->pending_preemption = false;
     147        this->kernel_thread = pthread_self();
    158148
    159149        this->runner = runner;
    160         LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
     150        LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
    161151        runner{ this };
    162152}
     153
     154LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    163155
    164156void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    168160
    169161        (&this->proc){ cltr, runner };
     162
     163        verify( validate( &this->alarms ) );
    170164}
    171165
     
    174168                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
    175169                this->is_terminated = true;
    176                 wait( &this->terminated );
     170                P( &this->terminated );
     171                pthread_join( this->kernel_thread, NULL );
    177172        }
    178173}
     
    209204                        if(readyThread)
    210205                        {
     206                                verify( disable_preempt_count > 0 );
     207
    211208                                runThread(this, readyThread);
     209
     210                                verify( disable_preempt_count > 0 );
    212211
    213212                                //Some actions need to be taken from the kernel
     
    225224        }
    226225
    227         signal( &this->terminated );
     226        V( &this->terminated );
     227
    228228        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
    229229}
     
    239239
    240240        //Update global state
    241         this->current_thread = dst;
     241        this_thread = dst;
    242242
    243243        // Context Switch to the thread
     
    289289        processor * proc = (processor *) arg;
    290290        this_processor = proc;
     291        this_coroutine = NULL;
     292        this_thread = NULL;
     293        disable_preempt_count = 1;
    291294        // SKULLDUGGERY: We want to create a context for the processor coroutine
    292295        // which is needed for the 2-step context switch. However, there is no reason
     
    300303
    301304        //Set global state
    302         proc->current_coroutine = &proc->runner->__cor;
    303         proc->current_thread = NULL;
     305        this_coroutine = &proc->runner->__cor;
     306        this_thread = NULL;
    304307
    305308        //We now have a proper context from which to schedule threads
     
    331334// Scheduler routines
    332335void ScheduleThread( thread_desc * thrd ) {
    333         if( !thrd ) return;
     336        // if( !thrd ) return;
     337        assert( thrd );
     338        assert( thrd->cor.state != Halted );
     339
     340        verify( disable_preempt_count > 0 );
    334341
    335342        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    336343
    337         lock( &systemProcessor->proc.cltr->lock );
     344        lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );
    338345        append( &systemProcessor->proc.cltr->ready_queue, thrd );
    339346        unlock( &systemProcessor->proc.cltr->lock );
     347
     348        verify( disable_preempt_count > 0 );
    340349}
    341350
    342351thread_desc * nextThread(cluster * this) {
    343         lock( &this->lock );
     352        verify( disable_preempt_count > 0 );
     353        lock( &this->lock DEBUG_CTX2 );
    344354        thread_desc * head = pop_head( &this->ready_queue );
    345355        unlock( &this->lock );
     356        verify( disable_preempt_count > 0 );
    346357        return head;
    347358}
    348359
    349 void ScheduleInternal() {
     360void BlockInternal() {
     361        disable_interrupts();
     362        verify( disable_preempt_count > 0 );
    350363        suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     364        verify( disable_preempt_count > 0 );
     365        enable_interrupts( DEBUG_CTX );
     366}
     367
     368void BlockInternal( spinlock * lock ) {
     369        disable_interrupts();
    354370        this_processor->finish.action_code = Release;
    355371        this_processor->finish.lock = lock;
     372
     373        verify( disable_preempt_count > 0 );
    356374        suspend();
    357 }
    358 
    359 void ScheduleInternal( thread_desc * thrd ) {
     375        verify( disable_preempt_count > 0 );
     376
     377        enable_interrupts( DEBUG_CTX );
     378}
     379
     380void BlockInternal( thread_desc * thrd ) {
     381        disable_interrupts();
     382        assert( thrd->cor.state != Halted );
    360383        this_processor->finish.action_code = Schedule;
    361384        this_processor->finish.thrd = thrd;
     385
     386        verify( disable_preempt_count > 0 );
    362387        suspend();
    363 }
    364 
    365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
     388        verify( disable_preempt_count > 0 );
     389
     390        enable_interrupts( DEBUG_CTX );
     391}
     392
     393void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     394        disable_interrupts();
    366395        this_processor->finish.action_code = Release_Schedule;
    367396        this_processor->finish.lock = lock;
    368397        this_processor->finish.thrd = thrd;
     398
     399        verify( disable_preempt_count > 0 );
    369400        suspend();
    370 }
    371 
    372 void ScheduleInternal(spinlock ** locks, unsigned short count) {
     401        verify( disable_preempt_count > 0 );
     402
     403        enable_interrupts( DEBUG_CTX );
     404}
     405
     406void BlockInternal(spinlock ** locks, unsigned short count) {
     407        disable_interrupts();
    373408        this_processor->finish.action_code = Release_Multi;
    374409        this_processor->finish.locks = locks;
    375410        this_processor->finish.lock_count = count;
     411
     412        verify( disable_preempt_count > 0 );
    376413        suspend();
    377 }
    378 
    379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     414        verify( disable_preempt_count > 0 );
     415
     416        enable_interrupts( DEBUG_CTX );
     417}
     418
     419void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     420        disable_interrupts();
    380421        this_processor->finish.action_code = Release_Multi_Schedule;
    381422        this_processor->finish.locks = locks;
     
    383424        this_processor->finish.thrds = thrds;
    384425        this_processor->finish.thrd_count = thrd_count;
     426
     427        verify( disable_preempt_count > 0 );
     428        suspend();
     429        verify( disable_preempt_count > 0 );
     430
     431        enable_interrupts( DEBUG_CTX );
     432}
     433
     434void LeaveThread(spinlock * lock, thread_desc * thrd) {
     435        verify( disable_preempt_count > 0 );
     436        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
     437        this_processor->finish.lock = lock;
     438        this_processor->finish.thrd = thrd;
     439
    385440        suspend();
    386441}
     
    397452        // SKULLDUGGERY: the mainThread steals the process main thread
    398453        // which will then be scheduled by the systemProcessor normally
    399         mainThread = (thread_desc *)&mainThread_storage;
     454        mainThread = (thread_desc *)&mainThreadStorage;
    400455        current_stack_info_t info;
    401456        mainThread{ &info };
     
    403458        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404459
    405         // Enable preemption
    406         kernel_start_preemption();
    407 
    408460        // Initialize the system cluster
    409         systemCluster = (cluster *)&systemCluster_storage;
     461        systemCluster = (cluster *)&systemClusterStorage;
    410462        systemCluster{};
    411463
     
    414466        // Initialize the system processor and the system processor ctx
    415467        // (the coroutine that contains the processing control flow)
    416         systemProcessor = (system_proc_t *)&systemProcessor_storage;
    417         systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
     468        systemProcessor = (system_proc_t *)&systemProcessorStorage;
     469        systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage };
    418470
    419471        // Add the main thread to the ready queue
     
    423475        //initialize the global state variables
    424476        this_processor = &systemProcessor->proc;
    425         this_processor->current_thread = mainThread;
    426         this_processor->current_coroutine = &mainThread->cor;
     477        this_thread = mainThread;
     478        this_coroutine = &mainThread->cor;
     479        disable_preempt_count = 1;
     480
     481        // Enable preemption
     482        kernel_start_preemption();
    427483
    428484        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
     
    435491        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436492        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     493
     494        enable_interrupts( DEBUG_CTX );
    437495}
    438496
    439497void kernel_shutdown(void) {
    440498        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
     499
     500        disable_interrupts();
    441501
    442502        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    448508        // THE SYSTEM IS NOW COMPLETELY STOPPED
    449509
     510        // Disable preemption
     511        kernel_stop_preemption();
     512
    450513        // Destroy the system processor and its context in reverse order of construction
    451514        // These were manually constructed so we need manually destroy them
     
    467530        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    468531        // the globalAbort flag is true.
    469         lock( &kernel_abort_lock );
     532        lock( &kernel_abort_lock DEBUG_CTX2 );
    470533
    471534        // first task to abort ?
     
    485548        }
    486549
    487         return this_thread();
     550        return this_thread;
    488551}
    489552
     
    494557        __lib_debug_write( STDERR_FILENO, abort_text, len );
    495558
    496         if ( thrd != this_coroutine() ) {
    497                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine()->name, this_coroutine() );
     559        if ( thrd != this_coroutine ) {
     560                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
    498561                __lib_debug_write( STDERR_FILENO, abort_text, len );
    499562        }
     
    505568extern "C" {
    506569        void __lib_debug_acquire() {
    507                 lock(&kernel_debug_lock);
     570                lock( &kernel_debug_lock DEBUG_CTX2 );
    508571        }
    509572
    510573        void __lib_debug_release() {
    511                 unlock(&kernel_debug_lock);
     574                unlock( &kernel_debug_lock );
    512575        }
    513576}
     
    525588}
    526589
    527 bool try_lock( spinlock * this ) {
     590bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    528591        return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;
    529592}
    530593
    531 void lock( spinlock * this ) {
     594void lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    532595        for ( unsigned int i = 1;; i += 1 ) {
    533                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break;
    534         }
    535 }
     596                if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
     597        }
     598        LIB_DEBUG_DO(
     599                this->prev_name = caller;
     600                this->prev_thrd = this_thread;
     601        )
     602}
     603
     604void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) {
     605        for ( unsigned int i = 1;; i += 1 ) {
     606                if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
     607                yield();
     608        }
     609        LIB_DEBUG_DO(
     610                this->prev_name = caller;
     611                this->prev_thrd = this_thread;
     612        )
     613}
     614
    536615
    537616void unlock( spinlock * this ) {
     
    539618}
    540619
    541 void ?{}( signal_once * this ) {
    542         this->cond = false;
    543 }
    544 void ^?{}( signal_once * this ) {
    545 
    546 }
    547 
    548 void wait( signal_once * this ) {
    549         lock( &this->lock );
    550         if( !this->cond ) {
    551                 append( &this->blocked, this_thread() );
    552                 ScheduleInternal( &this->lock );
    553                 lock( &this->lock );
    554         }
     620void  ?{}( semaphore * this, int count = 1 ) {
     621        (&this->lock){};
     622        this->count = count;
     623        (&this->waiting){};
     624}
     625void ^?{}(semaphore * this) {}
     626
     627void P(semaphore * this) {
     628        lock( &this->lock DEBUG_CTX2 );
     629        this->count -= 1;
     630        if ( this->count < 0 ) {
     631                // queue current task
     632                append( &this->waiting, (thread_desc *)this_thread );
     633
     634                // atomically release spin lock and block
     635                BlockInternal( &this->lock );
     636        }
     637        else {
     638            unlock( &this->lock );
     639        }
     640}
     641
     642void V(semaphore * this) {
     643        thread_desc * thrd = NULL;
     644        lock( &this->lock DEBUG_CTX2 );
     645        this->count += 1;
     646        if ( this->count <= 0 ) {
     647                // remove task at head of waiting list
     648                thrd = pop_head( &this->waiting );
     649        }
     650
    555651        unlock( &this->lock );
    556 }
    557 
    558 void signal( signal_once * this ) {
    559         lock( &this->lock );
    560         {
    561                 this->cond = true;
    562 
    563                 thread_desc * it;
    564                 while( it = pop_head( &this->blocked) ) {
    565                         ScheduleThread( it );
    566                 }
    567         }
    568         unlock( &this->lock );
     652
     653        // make new owner
     654        WakeThread( thrd );
    569655}
    570656
  • src/libcfa/concurrency/kernel_private.h

    r7812f1d1 rf73f5f4  
    1818#define KERNEL_PRIVATE_H
    1919
     20#include "libhdr.h"
     21
    2022#include "kernel"
    2123#include "thread"
     
    2325#include "alarm.h"
    2426
    25 #include "libhdr.h"
    2627
    2728//-----------------------------------------------------------------------------
    2829// Scheduler
     30
     31extern "C" {
     32        void disable_interrupts();
     33        void enable_interrupts_noRF();
     34        void enable_interrupts( DEBUG_CTX_PARAM );
     35}
     36
    2937void ScheduleThread( thread_desc * );
     38static inline void WakeThread( thread_desc * thrd ) {
     39        if( !thrd ) return;
     40
     41        disable_interrupts();
     42        ScheduleThread( thrd );
     43        enable_interrupts( DEBUG_CTX );
     44}
    3045thread_desc * nextThread(cluster * this);
    3146
    32 void ScheduleInternal(void);
    33 void ScheduleInternal(spinlock * lock);
    34 void ScheduleInternal(thread_desc * thrd);
    35 void ScheduleInternal(spinlock * lock, thread_desc * thrd);
    36 void ScheduleInternal(spinlock ** locks, unsigned short count);
    37 void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     47void BlockInternal(void);
     48void BlockInternal(spinlock * lock);
     49void BlockInternal(thread_desc * thrd);
     50void BlockInternal(spinlock * lock, thread_desc * thrd);
     51void BlockInternal(spinlock ** locks, unsigned short count);
     52void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     53void LeaveThread(spinlock * lock, thread_desc * thrd);
    3854
    3955//-----------------------------------------------------------------------------
     
    6076extern cluster * systemCluster;
    6177extern system_proc_t * systemProcessor;
    62 extern thread_local processor * this_processor;
    63 
    64 static 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 
    69 static 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 
    74 static 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         }
    81 }
     78extern volatile thread_local processor * this_processor;
     79extern volatile thread_local coroutine_desc * this_coroutine;
     80extern volatile thread_local thread_desc * this_thread;
     81extern volatile thread_local unsigned short disable_preempt_count;
    8282
    8383//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor

    r7812f1d1 rf73f5f4  
    2626static inline void ?{}(monitor_desc * this) {
    2727        this->owner = NULL;
    28         this->stack_owner = NULL;
    2928        this->recursion = 0;
    3029}
  • src/libcfa/concurrency/monitor.c

    r7812f1d1 rf73f5f4  
    1919#include <stdlib>
    2020
     21#include "libhdr.h"
    2122#include "kernel_private.h"
    22 #include "libhdr.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "C" {
    46         void __enter_monitor_desc(monitor_desc * this) {
    47                 lock( &this->lock );
    48                 thread_desc * thrd = this_thread();
    49 
    50                 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     46        void __enter_monitor_desc( monitor_desc * this ) {
     47                lock_yield( &this->lock DEBUG_CTX2 );
     48                thread_desc * thrd = this_thread;
     49
     50                // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    5151
    5252                if( !this->owner ) {
     
    6262                        //Some one else has the monitor, wait in line for it
    6363                        append( &this->entry_queue, thrd );
    64                         LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    65                         ScheduleInternal( &this->lock );
    66 
    67                         //ScheduleInternal will unlock spinlock, no need to unlock ourselves
    68                         return; 
     64                        // 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
     68                        return;
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      TODO
    77         void __leave_monitor_desc(monitor_desc * this) {
    78                 lock( &this->lock );
    79 
    80                 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    81                 verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );
     77        void __leave_monitor_desc( monitor_desc * this ) {
     78                lock_yield( &this->lock DEBUG_CTX2 );
     79
     80                // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
     81                verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
    8282
    8383                //Leaving a recursion level, decrement the counter
     
    9696                unlock( &this->lock );
    9797
    98                 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
     98                // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    9999
    100100                //We need to wake-up the thread
    101                 ScheduleThread( new_owner );
     101                WakeThread( new_owner );
     102        }
     103
     104        void __leave_thread_monitor( thread_desc * thrd ) {
     105                monitor_desc * this = &thrd->mon;
     106                lock_yield( &this->lock DEBUG_CTX2 );
     107
     108                disable_interrupts();
     109
     110                thrd->cor.state = Halted;
     111
     112                verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
     113
     114                //Leaving a recursion level, decrement the counter
     115                this->recursion -= 1;
     116
     117                //If we haven't left the last level of recursion
     118                //it means we don't need to do anything
     119                if( this->recursion != 0) {
     120                        unlock( &this->lock );
     121                        return;
     122                }
     123
     124                thread_desc * new_owner = next_thread( this );
     125
     126                LeaveThread( &this->lock, new_owner );
    102127        }
    103128}
     
    121146        enter( this->m, this->count );
    122147
    123         this->prev_mntrs = this_thread()->current_monitors;
    124         this->prev_count = this_thread()->current_monitor_count;
    125 
    126         this_thread()->current_monitors      = m;
    127         this_thread()->current_monitor_count = count;
     148        this->prev_mntrs = this_thread->current_monitors;
     149        this->prev_count = this_thread->current_monitor_count;
     150
     151        this_thread->current_monitors      = m;
     152        this_thread->current_monitor_count = count;
    128153}
    129154
     
    131156        leave( this->m, this->count );
    132157
    133         this_thread()->current_monitors      = this->prev_mntrs;
    134         this_thread()->current_monitor_count = this->prev_count;
     158        this_thread->current_monitors      = this->prev_mntrs;
     159        this_thread->current_monitor_count = this->prev_count;
    135160}
    136161
     
    159184// Internal scheduling
    160185void wait( condition * this, uintptr_t user_info = 0 ) {
    161         LIB_DEBUG_PRINT_SAFE("Waiting\n");
     186        // LIB_DEBUG_PRINT_SAFE("Waiting\n");
    162187
    163188        brand_condition( this );
     
    170195        unsigned short count = this->monitor_count;
    171196        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 ScheduleInternal
    173 
    174         LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    175 
    176         __condition_node_t waiter = { this_thread(), count, user_info };
     197        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
     198
     199        // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
     200
     201        __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
    177202
    178203        __condition_criterion_t criteria[count];
    179204        for(int i = 0; i < count; i++) {
    180205                (&criteria[i]){ this->monitors[i], &waiter };
    181                 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     206                // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    182207        }
    183208
     
    201226        }
    202227
    203         LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     228        // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    204229        for(int i = 0; i < thread_count; i++) {
    205                 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    206         }
    207         LIB_DEBUG_PRINT_SAFE("\n");
     230                // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     231        }
     232        // LIB_DEBUG_PRINT_SAFE("\n");
    208233
    209234        // Everything is ready to go to sleep
    210         ScheduleInternal( locks, count, threads, thread_count );
     235        BlockInternal( locks, count, threads, thread_count );
    211236
    212237
     
    222247bool signal( condition * this ) {
    223248        if( is_empty( this ) ) {
    224                 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     249                // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    225250                return false;
    226251        }
     
    231256
    232257        unsigned short count = this->monitor_count;
    233        
     258
    234259        //Some more checking in debug
    235260        LIB_DEBUG_DO(
    236                 thread_desc * this_thrd = this_thread();
     261                thread_desc * this_thrd = this_thread;
    237262                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    238263                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
     
    248273        //Lock all the monitors
    249274        lock_all( this->monitors, NULL, count );
    250         LIB_DEBUG_PRINT_SAFE("Signalling");
     275        // LIB_DEBUG_PRINT_SAFE("Signalling");
    251276
    252277        //Pop the head of the waiting queue
     
    256281        for(int i = 0; i < count; i++) {
    257282                __condition_criterion_t * crit = &node->criteria[i];
    258                 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     283                // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    259284                assert( !crit->ready );
    260285                push( &crit->target->signal_stack, crit );
    261286        }
    262287
    263         LIB_DEBUG_PRINT_SAFE("\n");
     288        // LIB_DEBUG_PRINT_SAFE("\n");
    264289
    265290        //Release
     
    281306        unsigned short count = this->monitor_count;
    282307        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 ScheduleInternal
     308        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    284309
    285310        lock_all( this->monitors, locks, count );
    286311
    287312        //create creteria
    288         __condition_node_t waiter = { this_thread(), count, 0 };
     313        __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
    289314
    290315        __condition_criterion_t criteria[count];
    291316        for(int i = 0; i < count; i++) {
    292317                (&criteria[i]){ this->monitors[i], &waiter };
    293                 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     318                // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    294319                push( &criteria[i].target->signal_stack, &criteria[i] );
    295320        }
     
    309334
    310335        //Everything is ready to go to sleep
    311         ScheduleInternal( locks, count, &signallee, 1 );
     336        BlockInternal( locks, count, &signallee, 1 );
    312337
    313338
     
    325350
    326351uintptr_t front( condition * this ) {
    327         verifyf( !is_empty(this), 
     352        verifyf( !is_empty(this),
    328353                "Attempt to access user data on an empty condition.\n"
    329354                "Possible cause is not checking if the condition is empty before reading stored data."
     
    335360// Internal scheduling
    336361void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    337         // thread_desc * this = this_thread();
     362        // thread_desc * this = this_thread;
    338363
    339364        // unsigned short count = this->current_monitor_count;
    340365        // 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 ScheduleInternal
     366        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
    342367
    343368        // lock_all( this->current_monitors, locks, count );
     
    348373
    349374        // // // Everything is ready to go to sleep
    350         // // ScheduleInternal( locks, count, threads, thread_count );
     375        // // BlockInternal( locks, count, threads, thread_count );
    351376
    352377
     
    393418static inline void lock_all( spinlock ** locks, unsigned short count ) {
    394419        for( int i = 0; i < count; i++ ) {
    395                 lock( locks[i] );
     420                lock_yield( locks[i] DEBUG_CTX2 );
    396421        }
    397422}
     
    400425        for( int i = 0; i < count; i++ ) {
    401426                spinlock * l = &source[i]->lock;
    402                 lock( l );
     427                lock_yield( l DEBUG_CTX2 );
    403428                if(locks) locks[i] = l;
    404429        }
     
    443468        for(    int i = 0; i < count; i++ ) {
    444469
    445                 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     470                // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    446471                if( &criteria[i] == target ) {
    447472                        criteria[i].ready = true;
    448                         LIB_DEBUG_PRINT_SAFE( "True\n" );
     473                        // LIB_DEBUG_PRINT_SAFE( "True\n" );
    449474                }
    450475
     
    452477        }
    453478
    454         LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     479        // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    455480        return ready2run ? node->waiting_thread : NULL;
    456481}
    457482
    458483static inline void brand_condition( condition * this ) {
    459         thread_desc * thrd = this_thread();
     484        thread_desc * thrd = this_thread;
    460485        if( !this->monitors ) {
    461                 LIB_DEBUG_PRINT_SAFE("Branding\n");
     486                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    462487                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    463488                this->monitor_count = thrd->current_monitor_count;
  • src/libcfa/concurrency/preemption.c

    r7812f1d1 rf73f5f4  
    1515//
    1616
     17#include "libhdr.h"
    1718#include "preemption.h"
    1819
    1920extern "C" {
     21#include <errno.h>
     22#include <execinfo.h>
     23#define __USE_GNU
    2024#include <signal.h>
    21 }
    22 
    23 #define __CFA_DEFAULT_PREEMPTION__ 10
     25#undef __USE_GNU
     26#include <stdio.h>
     27#include <string.h>
     28#include <unistd.h>
     29}
     30
     31
     32#ifdef __USE_STREAM__
     33#include "fstream"
     34#endif
     35
     36#define __CFA_DEFAULT_PREEMPTION__ 10000
    2437
    2538__attribute__((weak)) unsigned int default_preemption() {
     
    2740}
    2841
     42#define __CFA_SIGCXT__ ucontext_t *
     43#define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt
     44
    2945static void preempt( processor   * this );
    3046static void timeout( thread_desc * this );
    3147
     48void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
     49void sigHandler_alarm    ( __CFA_SIGPARMS__ );
     50void sigHandler_segv     ( __CFA_SIGPARMS__ );
     51void sigHandler_abort    ( __CFA_SIGPARMS__ );
     52
     53static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
     54LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
     55
     56#ifdef __x86_64__
     57#define CFA_REG_IP REG_RIP
     58#else
     59#define CFA_REG_IP REG_EIP
     60#endif
     61
     62
    3263//=============================================================================================
    3364// Kernel Preemption logic
    3465//=============================================================================================
    3566
    36 void kernel_start_preemption() {
    37 
    38 }
    39 
    4067void tick_preemption() {
     68        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );
     69
    4170        alarm_list_t * alarms = &systemProcessor->alarms;
    4271        __cfa_time_t currtime = __kernel_get_time();
    4372        while( alarms->head && alarms->head->alarm < currtime ) {
    4473                alarm_node_t * node = pop(alarms);
     74                // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node );
     75
    4576                if( node->kernel_alarm ) {
    4677                        preempt( node->proc );
     
    5081                }
    5182
     83                verify( validate( alarms ) );
     84
    5285                if( node->period > 0 ) {
    53                         node->alarm += node->period;
     86                        node->alarm = currtime + node->period;
    5487                        insert( alarms, node );
    5588                }
     
    6295                __kernel_set_timer( alarms->head->alarm - currtime );
    6396        }
     97
     98        verify( validate( alarms ) );
     99        // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" );
    64100}
    65101
    66102void update_preemption( processor * this, __cfa_time_t duration ) {
    67         //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
     103        LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration );
     104
    68105        alarm_node_t * alarm = this->preemption_alarm;
     106        duration *= 1000;
    69107
    70108        // Alarms need to be enabled
     
    89127}
    90128
     129//=============================================================================================
     130// Kernel Signal Tools
     131//=============================================================================================
     132
     133LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
     134
     135extern "C" {
     136        void disable_interrupts() {
     137                __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
     138                verify( new_val < (unsigned short)65_000 );
     139                verify( new_val != (unsigned short) 0 );
     140        }
     141
     142        void enable_interrupts_noRF() {
     143                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     144                verify( prev != (unsigned short) 0 );
     145        }
     146
     147        void enable_interrupts( DEBUG_CTX_PARAM ) {
     148                processor * proc   = this_processor;
     149                thread_desc * thrd = this_thread;
     150                unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     151                verify( prev != (unsigned short) 0 );
     152                if( prev == 1 && proc->pending_preemption ) {
     153                        proc->pending_preemption = false;
     154                        BlockInternal( thrd );
     155                }
     156
     157                LIB_DEBUG_DO( proc->last_enable = caller; )
     158        }
     159}
     160
     161static inline void signal_unblock( int sig ) {
     162        sigset_t mask;
     163        sigemptyset( &mask );
     164        sigaddset( &mask, sig );
     165
     166        if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {
     167            abortf( "internal error, pthread_sigmask" );
     168        }
     169}
     170
     171static inline void signal_block( int sig ) {
     172        sigset_t mask;
     173        sigemptyset( &mask );
     174        sigaddset( &mask, sig );
     175
     176        if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     177            abortf( "internal error, pthread_sigmask" );
     178        }
     179}
     180
     181static inline bool preemption_ready() {
     182        return disable_preempt_count == 0;
     183}
     184
     185static inline void defer_ctxSwitch() {
     186        this_processor->pending_preemption = true;
     187}
     188
     189static inline void defer_alarm() {
     190        systemProcessor->pending_alarm = true;
     191}
     192
     193static void preempt( processor * this ) {
     194        pthread_kill( this->kernel_thread, SIGUSR1 );
     195}
     196
     197static void timeout( thread_desc * this ) {
     198        //TODO : implement waking threads
     199}
     200
     201//=============================================================================================
     202// Kernel Signal Startup/Shutdown logic
     203//=============================================================================================
     204
     205static pthread_t alarm_thread;
     206void * alarm_loop( __attribute__((unused)) void * args );
     207
     208void kernel_start_preemption() {
     209        LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");
     210        __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO );
     211        // __kernel_sigaction( SIGSEGV, sigHandler_segv     , SA_SIGINFO );
     212        // __kernel_sigaction( SIGBUS , sigHandler_segv     , SA_SIGINFO );
     213
     214        signal_block( SIGALRM );
     215
     216        pthread_create( &alarm_thread, NULL, alarm_loop, NULL );
     217}
     218
     219void kernel_stop_preemption() {
     220        sigset_t mask;
     221        sigfillset( &mask );
     222        sigprocmask( SIG_BLOCK, &mask, NULL );
     223
     224        pthread_kill( alarm_thread, SIGINT );
     225        pthread_join( alarm_thread, NULL );
     226        LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");
     227}
     228
    91229void ?{}( preemption_scope * this, processor * proc ) {
    92230        (&this->alarm){ proc };
     
    97235
    98236void ^?{}( preemption_scope * this ) {
     237        disable_interrupts();
     238
    99239        update_preemption( this->proc, 0 );
    100240}
    101241
    102242//=============================================================================================
    103 // Kernel Signal logic
    104 //=============================================================================================
    105 
    106 static inline bool preemption_ready() {
    107         return this_processor->disable_preempt_count == 0;
    108 }
    109 
    110 static inline void defer_ctxSwitch() {
    111         this_processor->pending_preemption = true;
    112 }
    113 
    114 static inline void defer_alarm() {
    115         systemProcessor->pending_alarm = true;
    116 }
    117 
    118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
     243// Kernel Signal Handlers
     244//=============================================================================================
     245
     246void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
     247        LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
    119248        if( preemption_ready() ) {
    120                 ScheduleInternal( this_processor->current_thread );
     249                signal_unblock( SIGUSR1 );
     250                BlockInternal( (thread_desc*)this_thread );
    121251        }
    122252        else {
     
    125255}
    126256
    127 void 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 
    137 static void preempt( processor * this ) {
    138         pthread_kill( this->kernel_thread, SIGUSR1 );
    139 }
    140 
    141 static void timeout( thread_desc * this ) {
    142         //TODO : implement waking threads
    143 }
     257// void sigHandler_alarm( __CFA_SIGPARMS__ ) {
     258//      LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
     259//      verify( this_processor == systemProcessor );
     260
     261//      if( try_lock( &systemProcessor->alarm_lock DEBUG_CTX2 ) ) {
     262//              tick_preemption();
     263//              systemProcessor->pending_alarm = false;
     264//              unlock( &systemProcessor->alarm_lock );
     265//      }
     266//      else {
     267//              defer_alarm();
     268//      }
     269
     270//      signal_unblock( SIGALRM );
     271
     272//      if( preemption_ready() && this_processor->pending_preemption ) {
     273
     274//              this_processor->pending_preemption = false;
     275//              BlockInternal( (thread_desc*)this_thread );
     276//      }
     277// }
     278
     279void * alarm_loop( __attribute__((unused)) void * args ) {
     280        sigset_t mask;
     281        sigemptyset( &mask );
     282        sigaddset( &mask, SIGALRM );
     283        sigaddset( &mask, SIGUSR2 );
     284        sigaddset( &mask, SIGINT  );
     285
     286        if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     287            abortf( "internal error, pthread_sigmask" );
     288        }
     289
     290        while( true ) {
     291                int sig;
     292                if( sigwait( &mask, &sig ) != 0  ) {
     293                        abortf( "internal error, sigwait" );
     294                }
     295
     296                switch( sig) {
     297                        case SIGALRM:
     298                                LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
     299                                lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     300                                tick_preemption();
     301                                unlock( &systemProcessor->alarm_lock );
     302                                break;
     303                        case SIGUSR2:
     304                                //TODO other actions
     305                                break;
     306                        case SIGINT:
     307                                LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n");
     308                                return NULL;
     309                        default:
     310                                abortf( "internal error, sigwait returned sig %d", sig );
     311                                break;
     312                }
     313        }
     314}
     315
     316static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
     317        struct sigaction act;
     318
     319        act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
     320        act.sa_flags = flags;
     321
     322        if ( sigaction( sig, &act, NULL ) == -1 ) {
     323                LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO,
     324                        " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
     325                        sig, handler, flags, errno, strerror( errno )
     326                );
     327                _exit( EXIT_FAILURE );
     328        }
     329}
     330
     331typedef void (*sa_handler_t)(int);
     332
     333static void __kernel_sigdefault( int sig ) {
     334        struct sigaction act;
     335
     336        // act.sa_handler = SIG_DFL;
     337        act.sa_flags = 0;
     338        sigemptyset( &act.sa_mask );
     339
     340        if ( sigaction( sig, &act, NULL ) == -1 ) {
     341                LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO,
     342                        " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
     343                        sig, errno, strerror( errno )
     344                );
     345                _exit( EXIT_FAILURE );
     346        }
     347}
     348
     349//=============================================================================================
     350// Terminating Signals logic
     351//=============================================================================================
     352
     353LIB_DEBUG_DO(
     354        static void __kernel_backtrace( int start ) {
     355                // skip first N stack frames
     356
     357                enum { Frames = 50 };
     358                void * array[Frames];
     359                int size = backtrace( array, Frames );
     360                char ** messages = backtrace_symbols( array, size );
     361
     362                // find executable name
     363                *index( messages[0], '(' ) = '\0';
     364                #ifdef __USE_STREAM__
     365                serr | "Stack back trace for:" | messages[0] | endl;
     366                #else
     367                fprintf( stderr, "Stack back trace for: %s\n", messages[0]);
     368                #endif
     369
     370                // skip last 2 stack frames after main
     371                for ( int i = start; i < size && messages != NULL; i += 1 ) {
     372                        char * name = NULL;
     373                        char * offset_begin = NULL;
     374                        char * offset_end = NULL;
     375
     376                        for ( char *p = messages[i]; *p; ++p ) {
     377                                // find parantheses and +offset
     378                                if ( *p == '(' ) {
     379                                        name = p;
     380                                }
     381                                else if ( *p == '+' ) {
     382                                        offset_begin = p;
     383                                }
     384                                else if ( *p == ')' ) {
     385                                        offset_end = p;
     386                                        break;
     387                                }
     388                        }
     389
     390                        // if line contains symbol print it
     391                        int frameNo = i - start;
     392                        if ( name && offset_begin && offset_end && name < offset_begin ) {
     393                                // delimit strings
     394                                *name++ = '\0';
     395                                *offset_begin++ = '\0';
     396                                *offset_end++ = '\0';
     397
     398                                #ifdef __USE_STREAM__
     399                                serr    | "("  | frameNo | ")" | messages[i] | ":"
     400                                        | name | "+" | offset_begin | offset_end | endl;
     401                                #else
     402                                fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
     403                                #endif
     404                        }
     405                        // otherwise, print the whole line
     406                        else {
     407                                #ifdef __USE_STREAM__
     408                                serr | "(" | frameNo | ")" | messages[i] | endl;
     409                                #else
     410                                fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );
     411                                #endif
     412                        }
     413                }
     414
     415                free( messages );
     416        }
     417)
     418
     419// void sigHandler_segv( __CFA_SIGPARMS__ ) {
     420//      LIB_DEBUG_DO(
     421//              #ifdef __USE_STREAM__
     422//              serr    | "*CFA runtime error* program cfa-cpp terminated with"
     423//                      | (sig == SIGSEGV ? "segment fault." : "bus error.")
     424//                      | endl;
     425//              #else
     426//              fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );
     427//              #endif
     428
     429//              // skip first 2 stack frames
     430//              __kernel_backtrace( 1 );
     431//      )
     432//      exit( EXIT_FAILURE );
     433// }
     434
     435// void sigHandler_abort( __CFA_SIGPARMS__ ) {
     436//      // skip first 6 stack frames
     437//      LIB_DEBUG_DO( __kernel_backtrace( 6 ); )
     438
     439//      // reset default signal handler
     440//      __kernel_sigdefault( SIGABRT );
     441
     442//      raise( SIGABRT );
     443// }
  • src/libcfa/concurrency/thread

    r7812f1d1 rf73f5f4  
    5454}
    5555
    56 thread_desc * this_thread(void);
     56extern volatile thread_local thread_desc * this_thread;
    5757
    5858forall( dtype T | is_thread(T) )
  • src/libcfa/concurrency/thread.c

    r7812f1d1 rf73f5f4  
    2828}
    2929
    30 extern thread_local processor * this_processor;
     30extern volatile thread_local processor * this_processor;
    3131
    3232//-----------------------------------------------------------------------------
     
    7171        coroutine_desc* thrd_c = get_coroutine(this);
    7272        thread_desc*  thrd_h = get_thread   (this);
    73         thrd_c->last = this_coroutine();
    74         this_processor->current_coroutine = thrd_c;
     73        thrd_c->last = this_coroutine;
    7574
    76         LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     75        // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    7776
     77        disable_interrupts();
    7878        create_stack(&thrd_c->stack, thrd_c->stack.size);
     79        this_coroutine = thrd_c;
    7980        CtxStart(this, CtxInvokeThread);
     81        assert( thrd_c->last->stack.context );
    8082        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8183
    8284        ScheduleThread(thrd_h);
     85        enable_interrupts( DEBUG_CTX );
    8386}
    8487
    8588void yield( void ) {
    86         ScheduleInternal( this_processor->current_thread );
     89        BlockInternal( (thread_desc *)this_thread );
    8790}
    8891
     
    9598void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9699        // set state of current coroutine to inactive
    97         src->state = Inactive;
     100        src->state = src->state == Halted ? Halted : Inactive;
    98101        dst->state = Active;
    99102
     
    103106        // set new coroutine that the processor is executing
    104107        // and context switch to it
    105         this_processor->current_coroutine = dst;
     108        this_coroutine = dst;
     109        assert( src->stack.context );
    106110        CtxSwitch( src->stack.context, dst->stack.context );
    107         this_processor->current_coroutine = src;
     111        this_coroutine = src;
    108112
    109113        // set state of new coroutine to active
    110         dst->state = Inactive;
     114        dst->state = dst->state == Halted ? Halted : Inactive;
    111115        src->state = Active;
    112116}
  • src/libcfa/libhdr/libalign.h

    r7812f1d1 rf73f5f4  
    1 //                              -*- Mode: C++ -*- 
     1//                              -*- Mode: C++ -*-
    22//
    33// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1818// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
    1919// option) any later version.
    20 // 
     20//
    2121// This library is distributed in the  hope that it will be useful, but WITHOUT
    2222// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
    2323// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
    2424// for more details.
    25 // 
     25//
    2626// You should  have received a  copy of the  GNU Lesser General  Public License
    2727// along  with this library.
    28 // 
     28//
    2929
    3030
     
    3333
    3434#include "assert"
     35#include <stdbool.h>
    3536
    36 // Minimum size used to align memory boundaries for memory allocations. 
     37// Minimum size used to align memory boundaries for memory allocations.
    3738#define libAlign() (sizeof(double))
    3839
  • src/libcfa/libhdr/libdebug.h

    r7812f1d1 rf73f5f4  
    1818
    1919#ifdef __CFA_DEBUG__
    20         #define LIB_DEBUG_DO(x) x
    21         #define LIB_NO_DEBUG_DO(x) ((void)0)
     20        #define LIB_DEBUG_DO(...) __VA_ARGS__
     21        #define LIB_NO_DEBUG_DO(...)
     22        #define DEBUG_CTX __PRETTY_FUNCTION__
     23        #define DEBUG_CTX2 , __PRETTY_FUNCTION__
     24        #define DEBUG_CTX_PARAM const char * caller
     25        #define DEBUG_CTX_PARAM2 , const char * caller
    2226#else
    23         #define LIB_DEBUG_DO(x) ((void)0)
    24         #define LIB_NO_DEBUG_DO(x) x     
     27        #define LIB_DEBUG_DO(...)
     28        #define LIB_NO_DEBUG_DO(...) __VA_ARGS__
     29        #define DEBUG_CTX
     30        #define DEBUG_CTX2
     31        #define DEBUG_CTX_PARAM
     32        #define DEBUG_CTX_PARAM2
    2533#endif
    2634
     
    5159
    5260#ifdef __CFA_DEBUG_PRINT__
    53       #define LIB_DEBUG_WRITE( fd, buffer, len )  __lib_debug_write( fd, buffer, len )
    54       #define LIB_DEBUG_ACQUIRE()                 __lib_debug_acquire()
    55       #define LIB_DEBUG_RELEASE()                 __lib_debug_release()
    56       #define LIB_DEBUG_PRINT_SAFE(...)           __lib_debug_print_safe   (__VA_ARGS__)
    57       #define LIB_DEBUG_PRINT_NOLOCK(...)         __lib_debug_print_nolock (__VA_ARGS__)
    58       #define LIB_DEBUG_PRINT_BUFFER(...)         __lib_debug_print_buffer (__VA_ARGS__)
     61        #define LIB_DEBUG_WRITE( fd, buffer, len )     __lib_debug_write( fd, buffer, len )
     62        #define LIB_DEBUG_ACQUIRE()                    __lib_debug_acquire()
     63        #define LIB_DEBUG_RELEASE()                    __lib_debug_release()
     64        #define LIB_DEBUG_PRINT_SAFE(...)              __lib_debug_print_safe   (__VA_ARGS__)
     65        #define LIB_DEBUG_PRINT_NOLOCK(...)            __lib_debug_print_nolock (__VA_ARGS__)
     66        #define LIB_DEBUG_PRINT_BUFFER(...)            __lib_debug_print_buffer (__VA_ARGS__)
     67        #define LIB_DEBUG_PRINT_BUFFER_DECL(fd, ...)   char text[256]; int len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len );
     68        #define LIB_DEBUG_PRINT_BUFFER_LOCAL(fd, ...)  len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len );
    5969#else
    60       #define LIB_DEBUG_WRITE(...)          ((void)0)
    61       #define LIB_DEBUG_ACQUIRE()           ((void)0)
    62       #define LIB_DEBUG_RELEASE()           ((void)0)
    63       #define LIB_DEBUG_PRINT_SAFE(...)     ((void)0)
    64       #define LIB_DEBUG_PRINT_NOLOCK(...)   ((void)0)
    65       #define LIB_DEBUG_PRINT_BUFFER(...)   ((void)0)
     70        #define LIB_DEBUG_WRITE(...)               ((void)0)
     71        #define LIB_DEBUG_ACQUIRE()                ((void)0)
     72        #define LIB_DEBUG_RELEASE()                ((void)0)
     73        #define LIB_DEBUG_PRINT_SAFE(...)          ((void)0)
     74        #define LIB_DEBUG_PRINT_NOLOCK(...)        ((void)0)
     75        #define LIB_DEBUG_PRINT_BUFFER(...)        ((void)0)
     76        #define LIB_DEBUG_PRINT_BUFFER_DECL(...)   ((void)0)
     77        #define LIB_DEBUG_PRINT_BUFFER_LOCAL(...)  ((void)0)
    6678#endif
    6779
  • src/tests/preempt_longrun/Makefile.am

    r7812f1d1 rf73f5f4  
    1717repeats=10
    1818max_time=30
    19 preempt=10_000ul
     19preempt=1_000ul
    2020
    2121REPEAT = ${abs_top_srcdir}/tools/repeat -s
     
    2525CC = @CFA_BINDIR@/@CFA_NAME@
    2626
    27 TESTS = barge block create disjoint processor stack wait yield
     27TESTS = barge block create disjoint enter enter3 processor stack wait yield
    2828
    2929.INTERMEDIATE: ${TESTS}
  • src/tests/preempt_longrun/Makefile.in

    r7812f1d1 rf73f5f4  
    450450repeats = 10
    451451max_time = 30
    452 preempt = 10_000ul
     452preempt = 1_000ul
    453453REPEAT = ${abs_top_srcdir}/tools/repeat -s
    454454BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt}
    455 TESTS = barge block create disjoint processor stack wait yield
     455TESTS = barge block create disjoint enter enter3 processor stack wait yield
    456456all: all-am
    457457
     
    663663        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
    664664        "$$tst" $(AM_TESTS_FD_REDIRECT)
     665enter.log: enter
     666        @p='enter'; \
     667        b='enter'; \
     668        $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
     669        --log-file $$b.log --trs-file $$b.trs \
     670        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
     671        "$$tst" $(AM_TESTS_FD_REDIRECT)
     672enter3.log: enter3
     673        @p='enter3'; \
     674        b='enter3'; \
     675        $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
     676        --log-file $$b.log --trs-file $$b.trs \
     677        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
     678        "$$tst" $(AM_TESTS_FD_REDIRECT)
    665679processor.log: processor
    666680        @p='processor'; \
  • src/tests/preempt_longrun/create.c

    r7812f1d1 rf73f5f4  
    1010}
    1111
    12 thread Worker {};
     12thread worker_t {};
    1313
    14 void main(Worker * this) {}
     14void main(worker_t * this) {}
    1515
    1616int main(int argc, char* argv[]) {
    17         for(int i = 0; i < 100_000ul; i++) {
    18                 Worker w;
     17        for(int i = 0; i < 10_000ul; i++) {
     18                worker_t w[7];
    1919        }
    2020}
  • src/tests/preempt_longrun/processor.c

    r7812f1d1 rf73f5f4  
    1010}
    1111
    12 thread Worker {};
     12thread worker_t {};
    1313
    14 void main(Worker * this) {}
     14void main(worker_t * this) {}
    1515
    1616int main(int argc, char* argv[]) {
    17         for(int i = 0; i < 100_000ul; i++) {
     17        for(int i = 0; i < 10_000ul; i++) {
    1818                processor p;
    1919        }
  • src/tests/preempt_longrun/stack.c

    r7812f1d1 rf73f5f4  
    1212}
    1313
    14 thread Worker {};
     14thread worker_t {};
    1515
    16 void main(Worker * this) {
     16void main(worker_t * this) {
    1717        volatile long p = 5_021_609ul;
    1818        volatile long a = 326_417ul;
    1919        volatile long n = 1l;
    20         for (volatile long i = 0; i < p; i++) { 
    21                 n *= a; 
    22                 n %= p; 
     20        for (volatile long i = 0; i < p; i++) {
     21                n *= a;
     22                n %= p;
    2323        }
    24                
     24
    2525        if( n != a ) {
    2626                abort();
     
    2828}
    2929
     30extern "C" {
     31static worker_t * workers;
     32}
     33
    3034int main(int argc, char* argv[]) {
    3135        processor p;
    3236        {
    33                 Worker w[7];
     37                worker_t w[7];
     38                workers = w;
    3439        }
    3540}
  • src/tests/preempt_longrun/yield.c

    r7812f1d1 rf73f5f4  
    1010}
    1111
    12 thread Worker {};
     12thread worker_t {};
    1313
    14 void main(Worker * this) {
    15         for(int i = 0; i < 100_000ul; i++) {
     14void main(worker_t * this) {
     15        for(int i = 0; i < 325_000ul; i++) {
    1616                yield();
    1717        }
     18}
     19
     20extern "C" {
     21static worker_t * workers;
    1822}
    1923
     
    2125        processor p;
    2226        {
    23                 Worker w[7];
     27                worker_t w[7];
     28                workers = w;
    2429        }
    2530}
  • src/tests/sched-int-block.c

    r7812f1d1 rf73f5f4  
    66
    77#ifndef N
    8 #define N 100_000
     8#define N 10_000
    99#endif
    1010
     
    3131//------------------------------------------------------------------------------
    3232void wait_op( global_data_t * mutex a, global_data_t * mutex b, unsigned i ) {
    33         wait( &cond, (uintptr_t)this_thread() );
     33        wait( &cond, (uintptr_t)this_thread );
    3434
    3535        yield( ((unsigned)rand48()) % 10 );
     
    4040        }
    4141
    42         a->last_thread = b->last_thread = this_thread();
     42        a->last_thread = b->last_thread = this_thread;
    4343
    4444        yield( ((unsigned)rand48()) % 10 );
     
    5656        yield( ((unsigned)rand48()) % 10 );
    5757
    58         a->last_thread = b->last_thread = a->last_signaller = b->last_signaller = this_thread();
     58        a->last_thread = b->last_thread = a->last_signaller = b->last_signaller = this_thread;
    5959
    6060        if( !is_empty( &cond ) ) {
     
    8686//------------------------------------------------------------------------------
    8787void barge_op( global_data_t * mutex a ) {
    88         a->last_thread = this_thread();
     88        a->last_thread = this_thread;
    8989}
    9090
  • src/tests/sched-int-disjoint.c

    r7812f1d1 rf73f5f4  
    55
    66#ifndef N
    7 #define N 100_000
     7#define N 10_000
    88#endif
    99
     
    4242
    4343void main( Barger * this ) {
    44         while( !all_done ) { 
     44        while( !all_done ) {
    4545                barge( &data );
    46                 yield(); 
     46                yield();
    4747        }
    4848}
     
    5353        wait( &cond );
    5454        if( d->state != SIGNAL ) {
    55                 sout | "ERROR barging!" | endl; 
     55                sout | "ERROR barging!" | endl;
    5656        }
    5757
     
    8585        bool running = data.counter < N && data.counter > 0;
    8686        if( data.state != SIGNAL && running ) {
    87                 sout | "ERROR Eager signal" | data.state | endl; 
     87                sout | "ERROR Eager signal" | data.state | endl;
    8888        }
    8989}
     
    9292
    9393void main( Signaller * this ) {
    94         while( !all_done ) { 
     94        while( !all_done ) {
    9595                logic( &mut );
    96                 yield(); 
     96                yield();
    9797        }
    9898}
     
    111111                sout | "All waiter done" | endl;
    112112                all_done = true;
    113         }       
     113        }
    114114}
  • src/tests/sched-int-wait.c

    r7812f1d1 rf73f5f4  
    5050                unsigned action = (unsigned)rand48() % 4;
    5151                switch( action ) {
    52                         case 0: 
     52                        case 0:
    5353                                signal( &condABC, &globalA, &globalB, &globalC );
    5454                                break;
    55                         case 1: 
     55                        case 1:
    5656                                signal( &condAB , &globalA, &globalB );
    5757                                break;
    58                         case 2: 
     58                        case 2:
    5959                                signal( &condBC , &globalB, &globalC );
    6060                                break;
    61                         case 3: 
     61                        case 3:
    6262                                signal( &condAC , &globalA, &globalC );
    6363                                break;
     
    6767                }
    6868                yield();
    69         }       
     69        }
    7070}
    7171
  • src/tests/thread.c

    r7812f1d1 rf73f5f4  
    44#include <thread>
    55
    6 // thread First;
    7 // void main(First* this);
     6thread First  { semaphore* lock; };
     7thread Second { semaphore* lock; };
    88
    9 // thread Second;
    10 // void main(Second* this);
    11 
    12 thread First  { signal_once* lock; };
    13 thread Second { signal_once* lock; };
    14 
    15 void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
    16 void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
     9void ?{}( First * this, semaphore* lock ) { this->lock = lock; }
     10void ?{}( Second * this, semaphore* lock ) { this->lock = lock; }
    1711
    1812void main(First* this) {
     
    2115                yield();
    2216        }
    23         signal(this->lock);
     17        V(this->lock);
    2418}
    2519
    2620void main(Second* this) {
    27         wait(this->lock);
     21        P(this->lock);
    2822        for(int i = 0; i < 10; i++) {
    2923                sout | "Second : Suspend No." | i + 1 | endl;
     
    3428
    3529int main(int argc, char* argv[]) {
    36         signal_once lock;
     30        semaphore lock = { 0 };
    3731        sout | "User main begin" | endl;
    3832        {
Note: See TracChangeset for help on using the changeset viewer.