Changes in / [0614d14:1ce2189]


Ignore:
Location:
src
Files:
5 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • src/benchmark/CorCtxSwitch.c

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

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

    r0614d14 r1ce2189  
    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}
    25 
    26 #include "libhdr.h"
    2721
    2822#include "alarm.h"
     
    3731        timespec curr;
    3832        clock_gettime( CLOCK_REALTIME, &curr );
    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;
     33        return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    4234}
    4335
    4436void __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 );
    4637        itimerval val;
    4738        val.it_value.tv_sec = alarm / TIMEGRAN;                 // seconds
     
    8071}
    8172
    82 LIB_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 
    9173static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    92         verify( !n->next );
     74        assert( !n->next );
    9375        if( p == this->tail ) {
    9476                this->tail = &n->next;
     
    9880        }
    9981        *p = n;
    100 
    101         verify( validate( this ) );
    10282}
    10383
     
    10989
    11090        insert_at( this, n, it );
    111 
    112         verify( validate( this ) );
    11391}
    11492
     
    122100                head->next = NULL;
    123101        }
    124         verify( validate( this ) );
    125102        return head;
    126103}
     
    128105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    129106        verify( it );
    130         verify( (*it) == n );
     107        verify( (*it)->next == n );
    131108
    132         (*it) = n->next;
     109        (*it)->next = n->next;
    133110        if( !n-> next ) {
    134111                this->tail = it;
    135112        }
    136113        n->next = NULL;
    137 
    138         verify( validate( this ) );
    139114}
    140115
    141116static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    142117        alarm_node_t ** it = &this->head;
    143         while( (*it) && (*it) != n ) {
     118        while( (*it) && (*it)->next != n ) {
    144119                it = &(*it)->next;
    145120        }
    146121
    147         verify( validate( this ) );
    148 
    149122        if( *it ) { remove_at( this, n, it ); }
    150 
    151         verify( validate( this ) );
    152123}
    153124
    154125void register_self( alarm_node_t * this ) {
    155126        disable_interrupts();
    156         verify( !systemProcessor->pending_alarm );
    157         lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     127        assert( !systemProcessor->pending_alarm );
     128        lock( &systemProcessor->alarm_lock );
    158129        {
    159                 verify( validate( &systemProcessor->alarms ) );
    160                 bool first = !systemProcessor->alarms.head;
    161 
    162130                insert( &systemProcessor->alarms, this );
    163131                if( systemProcessor->pending_alarm ) {
    164132                        tick_preemption();
    165133                }
    166                 if( first ) {
    167                         __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
    168                 }
    169134        }
    170135        unlock( &systemProcessor->alarm_lock );
    171136        this->set = true;
    172         enable_interrupts( DEBUG_CTX );
     137        enable_interrupts();
    173138}
    174139
    175140void unregister_self( alarm_node_t * this ) {
    176         // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );
    177141        disable_interrupts();
    178         lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    179         {
    180                 verify( validate( &systemProcessor->alarms ) );
    181                 remove( &systemProcessor->alarms, this );
    182         }
     142        lock( &systemProcessor->alarm_lock );
     143        remove( &systemProcessor->alarms, this );
    183144        unlock( &systemProcessor->alarm_lock );
    184         enable_interrupts( DEBUG_CTX );
     145        disable_interrupts();
    185146        this->set = false;
    186         // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );
    187147}
  • src/libcfa/concurrency/coroutine

    r0614d14 r1ce2189  
    6363
    6464// Get current coroutine
    65 extern volatile thread_local coroutine_desc * this_coroutine;
     65coroutine_desc * this_coroutine(void);
    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

    r0614d14 r1ce2189  
    3232#include "invoke.h"
    3333
    34 extern volatile thread_local processor * this_processor;
     34extern thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
     
    4444// Coroutine ctors and dtors
    4545void ?{}(coStack_t* this) {
    46         this->size              = 65000;        // size of stack
     46        this->size              = 10240;        // 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 = src->state == Halted ? Halted : Inactive;
     108        src->state = Inactive;
    109109
    110110        // set new coroutine that task is executing
    111         this_coroutine = dst;
     111        this_processor->current_coroutine = dst;
    112112
    113113        // context switch to specified coroutine
    114         assert( src->stack.context );
    115114        CtxSwitch( src->stack.context, dst->stack.context );
    116         // when CtxSwitch returns we are back in the src coroutine
     115        // when CtxSwitch returns we are back in the src coroutine             
    117116
    118117        // set state of new coroutine to active
     
    132131                this->size = libCeiling( storageSize, 16 );
    133132                // use malloc/memalign because "new" raises an exception for out-of-memory
    134 
     133               
    135134                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    136135                LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
  • src/libcfa/concurrency/invoke.c

    r0614d14 r1ce2189  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_thread_monitor( struct thread_desc * this );
    32 extern void disable_interrupts();
    33 extern void enable_interrupts( DEBUG_CTX_PARAM );
     31extern void __leave_monitor_desc( struct monitor_desc * this );
    3432
    3533void CtxInvokeCoroutine(
    36       void (*main)(void *),
    37       struct coroutine_desc *(*get_coroutine)(void *),
     34      void (*main)(void *), 
     35      struct coroutine_desc *(*get_coroutine)(void *), 
    3836      void *this
    3937) {
     
    5856
    5957void CtxInvokeThread(
    60       void (*dtor)(void *),
    61       void (*main)(void *),
    62       struct thread_desc *(*get_thread)(void *),
     58      void (*dtor)(void *), 
     59      void (*main)(void *), 
     60      struct thread_desc *(*get_thread)(void *), 
    6361      void *this
    6462) {
    65       // First suspend, once the thread arrives here,
    66       // the function pointer to main can be invalidated without risk
    6763      __suspend_internal();
    6864
    69       // Fetch the thread handle from the user defined thread structure
    7065      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;
    7169
    72       // Officially start the thread by enabling preemption
    73       enable_interrupts( DEBUG_CTX );
    74 
    75       // Call the main of the thread
     70      // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
    7671      main( this );
    7772
    78       // To exit a thread we must :
    79       // 1 - Mark it as halted
    80       // 2 - Leave its monitor
    81       // 3 - Disable the interupts
    82       // The order of these 3 operations is very important
    83       __leave_thread_monitor( thrd );
     73      __leave_monitor_desc( mon );
    8474
    8575      //Final suspend, should never return
     
    9080
    9181void CtxStart(
    92       void (*main)(void *),
    93       struct coroutine_desc *(*get_coroutine)(void *),
    94       void *this,
     82      void (*main)(void *), 
     83      struct coroutine_desc *(*get_coroutine)(void *), 
     84      void *this, 
    9585      void (*invoke)(void *)
    9686) {
     
    118108        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    119109      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    120       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     110      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
    121111
    122112#elif defined( __x86_64__ )
     
    138128      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
    139129      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    140       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     130      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
    141131#else
    142132      #error Only __i386__ and __x86_64__ is supported for threads in cfa
  • src/libcfa/concurrency/invoke.h

    r0614d14 r1ce2189  
    3131      struct spinlock {
    3232            volatile int lock;
    33             #ifdef __CFA_DEBUG__
    34                   const char * prev_name;
    35                   void* prev_thrd;
    36             #endif
    3733      };
    3834
     
    8783            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    8884            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
    8986            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    9087      };
     
    10299#ifndef _INVOKE_PRIVATE_H_
    103100#define _INVOKE_PRIVATE_H_
    104 
     101     
    105102      struct machine_context_t {
    106103            void *SP;
  • src/libcfa/concurrency/kernel

    r0614d14 r1ce2189  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
    31 void lock      ( spinlock * DEBUG_CTX_PARAM2 );
    32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
    33 void unlock    ( spinlock * );
     30bool try_lock( spinlock * );
     31void lock( spinlock * );
     32void unlock( spinlock * );
    3433
    3534struct signal_once {
     
    6968        unsigned short thrd_count;
    7069};
    71 static inline void ?{}(FinishAction * this) {
     70static inline void ?{}(FinishAction * this) { 
    7271        this->action_code = No_Action;
    7372        this->thrd = NULL;
     
    7978        struct processorCtx_t * runner;
    8079        cluster * cltr;
     80        coroutine_desc * current_coroutine;
     81        thread_desc * current_thread;
    8182        pthread_t kernel_thread;
    82 
     83       
    8384        signal_once terminated;
    8485        volatile bool is_terminated;
     
    8990        unsigned int preemption;
    9091
     92        unsigned short disable_preempt_count;
     93
    9194        bool pending_preemption;
    92 
    93         char * last_enable;
    9495};
    9596
  • src/libcfa/concurrency/kernel.c

    r0614d14 r1ce2189  
    1515//
    1616
    17 #include "libhdr.h"
     17#include "startup.h"
     18
     19//Start and stop routine for the kernel, declared first to make sure they run first
     20void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     21void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     22
     23//Header
     24#include "kernel_private.h"
    1825
    1926//C Includes
     
    2835
    2936//CFA Includes
    30 #include "kernel_private.h"
     37#include "libhdr.h"
    3138#include "preemption.h"
    32 #include "startup.h"
    3339
    3440//Private includes
    3541#define __CFA_INVOKE_PRIVATE__
    3642#include "invoke.h"
    37 
    38 //Start and stop routine for the kernel, declared first to make sure they run first
    39 void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    4143
    4244//-----------------------------------------------------------------------------
     
    5759// Global state
    5860
    59 volatile thread_local processor * this_processor;
    60 volatile thread_local coroutine_desc * this_coroutine;
    61 volatile thread_local thread_desc * this_thread;
    62 volatile thread_local unsigned short disable_preempt_count = 1;
     61thread_local processor * this_processor;
     62
     63coroutine_desc * this_coroutine(void) {
     64        return this_processor->current_coroutine;
     65}
     66
     67thread_desc * this_thread(void) {
     68        return this_processor->current_thread;
     69}
    6370
    6471//-----------------------------------------------------------------------------
    6572// Main thread construction
    6673struct current_stack_info_t {
    67         machine_context_t ctx;
     74        machine_context_t ctx; 
    6875        unsigned int size;              // size of stack
    6976        void *base;                             // base of stack
     
    99106
    100107void ?{}( coroutine_desc * this, current_stack_info_t * info) {
    101         (&this->stack){ info };
     108        (&this->stack){ info }; 
    102109        this->name = "Main Thread";
    103110        this->errno_ = 0;
     
    129136void ?{}(processor * this, cluster * cltr) {
    130137        this->cltr = cltr;
     138        this->current_coroutine = NULL;
     139        this->current_thread = NULL;
    131140        (&this->terminated){};
    132141        this->is_terminated = false;
    133142        this->preemption_alarm = NULL;
    134143        this->preemption = default_preemption();
     144        this->disable_preempt_count = 1;                //Start with interrupts disabled
    135145        this->pending_preemption = false;
    136146
     
    140150void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    141151        this->cltr = cltr;
     152        this->current_coroutine = NULL;
     153        this->current_thread = NULL;
    142154        (&this->terminated){};
    143155        this->is_terminated = false;
    144         this->preemption_alarm = NULL;
    145         this->preemption = default_preemption();
     156        this->disable_preempt_count = 0;
    146157        this->pending_preemption = false;
    147         this->kernel_thread = pthread_self();
    148158
    149159        this->runner = runner;
    150         LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
     160        LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
    151161        runner{ this };
    152162}
    153 
    154 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    155163
    156164void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    160168
    161169        (&this->proc){ cltr, runner };
    162 
    163         verify( validate( &this->alarms ) );
    164170}
    165171
     
    178184
    179185void ^?{}(cluster * this) {
    180 
     186       
    181187}
    182188
     
    197203
    198204                thread_desc * readyThread = NULL;
    199                 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ )
     205                for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 
    200206                {
    201207                        readyThread = nextThread( this->cltr );
     
    203209                        if(readyThread)
    204210                        {
    205                                 verify( disable_preempt_count > 0 );
    206 
    207211                                runThread(this, readyThread);
    208 
    209                                 verify( disable_preempt_count > 0 );
    210212
    211213                                //Some actions need to be taken from the kernel
     
    227229}
    228230
    229 // runThread runs a thread by context switching
    230 // from the processor coroutine to the target thread
     231// runThread runs a thread by context switching 
     232// from the processor coroutine to the target thread 
    231233void runThread(processor * this, thread_desc * dst) {
    232234        coroutine_desc * proc_cor = get_coroutine(this->runner);
    233235        coroutine_desc * thrd_cor = get_coroutine(dst);
    234 
     236       
    235237        //Reset the terminating actions here
    236238        this->finish.action_code = No_Action;
    237239
    238240        //Update global state
    239         this_thread = dst;
     241        this->current_thread = dst;
    240242
    241243        // Context Switch to the thread
     
    244246}
    245247
    246 // Once a thread has finished running, some of
     248// Once a thread has finished running, some of 
    247249// its final actions must be executed from the kernel
    248250void finishRunning(processor * this) {
     
    254256        }
    255257        else if( this->finish.action_code == Release_Schedule ) {
    256                 unlock( this->finish.lock );
     258                unlock( this->finish.lock );           
    257259                ScheduleThread( this->finish.thrd );
    258260        }
     
    287289        processor * proc = (processor *) arg;
    288290        this_processor = proc;
    289         this_coroutine = NULL;
    290         this_thread = NULL;
    291         disable_preempt_count = 1;
    292291        // SKULLDUGGERY: We want to create a context for the processor coroutine
    293292        // which is needed for the 2-step context switch. However, there is no reason
    294         // to waste the perfectly valid stack create by pthread.
     293        // to waste the perfectly valid stack create by pthread. 
    295294        current_stack_info_t info;
    296295        machine_context_t ctx;
     
    301300
    302301        //Set global state
    303         this_coroutine = &proc->runner->__cor;
    304         this_thread = NULL;
     302        proc->current_coroutine = &proc->runner->__cor;
     303        proc->current_thread = NULL;
    305304
    306305        //We now have a proper context from which to schedule threads
    307306        LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
    308307
    309         // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
    310         // resume it to start it like it normally would, it will just context switch
    311         // back to here. Instead directly call the main since we already are on the
     308        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 
     309        // resume it to start it like it normally would, it will just context switch 
     310        // back to here. Instead directly call the main since we already are on the 
    312311        // appropriate stack.
    313312        proc_cor_storage.__cor.state = Active;
     
    316315
    317316        // Main routine of the core returned, the core is now fully terminated
    318         LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner);
     317        LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 
    319318
    320319        return NULL;
     
    323322void start(processor * this) {
    324323        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    325 
     324       
    326325        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    327326
    328         LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
     327        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
    329328}
    330329
     
    332331// Scheduler routines
    333332void ScheduleThread( thread_desc * thrd ) {
    334         // if( !thrd ) return;
    335         assert( thrd );
    336         assert( thrd->cor.state != Halted );
    337 
    338         verify( disable_preempt_count > 0 );
     333        if( !thrd ) return;
    339334
    340335        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    341 
    342         lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );
     336       
     337        lock( &systemProcessor->proc.cltr->lock );
    343338        append( &systemProcessor->proc.cltr->ready_queue, thrd );
    344339        unlock( &systemProcessor->proc.cltr->lock );
    345 
    346         verify( disable_preempt_count > 0 );
    347340}
    348341
    349342thread_desc * nextThread(cluster * this) {
    350         verify( disable_preempt_count > 0 );
    351         lock( &this->lock DEBUG_CTX2 );
     343        lock( &this->lock );
    352344        thread_desc * head = pop_head( &this->ready_queue );
    353345        unlock( &this->lock );
    354         verify( disable_preempt_count > 0 );
    355346        return head;
    356347}
    357348
    358 void BlockInternal() {
    359         disable_interrupts();
    360         verify( disable_preempt_count > 0 );
     349void ScheduleInternal() {
    361350        suspend();
    362         verify( disable_preempt_count > 0 );
    363         enable_interrupts( DEBUG_CTX );
    364 }
    365 
    366 void BlockInternal( spinlock * lock ) {
    367         disable_interrupts();
     351}
     352
     353void ScheduleInternal( spinlock * lock ) {
    368354        this_processor->finish.action_code = Release;
    369355        this_processor->finish.lock = lock;
    370 
    371         verify( disable_preempt_count > 0 );
    372356        suspend();
    373         verify( disable_preempt_count > 0 );
    374 
    375         enable_interrupts( DEBUG_CTX );
    376 }
    377 
    378 void BlockInternal( thread_desc * thrd ) {
    379         disable_interrupts();
    380         assert( thrd->cor.state != Halted );
     357}
     358
     359void ScheduleInternal( thread_desc * thrd ) {
    381360        this_processor->finish.action_code = Schedule;
    382361        this_processor->finish.thrd = thrd;
    383 
    384         verify( disable_preempt_count > 0 );
    385362        suspend();
    386         verify( disable_preempt_count > 0 );
    387 
    388         enable_interrupts( DEBUG_CTX );
    389 }
    390 
    391 void BlockInternal( spinlock * lock, thread_desc * thrd ) {
    392         disable_interrupts();
     363}
     364
     365void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
    393366        this_processor->finish.action_code = Release_Schedule;
    394367        this_processor->finish.lock = lock;
    395368        this_processor->finish.thrd = thrd;
    396 
    397         verify( disable_preempt_count > 0 );
    398369        suspend();
    399         verify( disable_preempt_count > 0 );
    400 
    401         enable_interrupts( DEBUG_CTX );
    402 }
    403 
    404 void BlockInternal(spinlock ** locks, unsigned short count) {
    405         disable_interrupts();
     370}
     371
     372void ScheduleInternal(spinlock ** locks, unsigned short count) {
    406373        this_processor->finish.action_code = Release_Multi;
    407374        this_processor->finish.locks = locks;
    408375        this_processor->finish.lock_count = count;
    409 
    410         verify( disable_preempt_count > 0 );
    411376        suspend();
    412         verify( disable_preempt_count > 0 );
    413 
    414         enable_interrupts( DEBUG_CTX );
    415 }
    416 
    417 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    418         disable_interrupts();
     377}
     378
     379void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    419380        this_processor->finish.action_code = Release_Multi_Schedule;
    420381        this_processor->finish.locks = locks;
     
    422383        this_processor->finish.thrds = thrds;
    423384        this_processor->finish.thrd_count = thrd_count;
    424 
    425         verify( disable_preempt_count > 0 );
    426385        suspend();
    427         verify( disable_preempt_count > 0 );
    428 
    429         enable_interrupts( DEBUG_CTX );
    430386}
    431387
     
    436392// Kernel boot procedures
    437393void kernel_startup(void) {
    438         LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");
     394        LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");   
    439395
    440396        // Start by initializing the main thread
    441         // SKULLDUGGERY: the mainThread steals the process main thread
     397        // SKULLDUGGERY: the mainThread steals the process main thread 
    442398        // which will then be scheduled by the systemProcessor normally
    443399        mainThread = (thread_desc *)&mainThread_storage;
     
    447403        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    448404
     405        // Enable preemption
     406        kernel_start_preemption();
     407
    449408        // Initialize the system cluster
    450409        systemCluster = (cluster *)&systemCluster_storage;
     
    458417        systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
    459418
    460         // Add the main thread to the ready queue
     419        // Add the main thread to the ready queue 
    461420        // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread
    462421        ScheduleThread(mainThread);
     
    464423        //initialize the global state variables
    465424        this_processor = &systemProcessor->proc;
    466         this_thread = mainThread;
    467         this_coroutine = &mainThread->cor;
    468         disable_preempt_count = 1;
    469 
    470         // Enable preemption
    471         kernel_start_preemption();
     425        this_processor->current_thread = mainThread;
     426        this_processor->current_coroutine = &mainThread->cor;
    472427
    473428        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
    474429        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    475         // mainThread is on the ready queue when this call is made.
     430        // mainThread is on the ready queue when this call is made. 
    476431        resume( systemProcessor->proc.runner );
    477432
     
    480435        // THE SYSTEM IS NOW COMPLETELY RUNNING
    481436        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
    482 
    483         enable_interrupts( DEBUG_CTX );
    484437}
    485438
    486439void kernel_shutdown(void) {
    487440        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
    488 
    489         disable_interrupts();
    490441
    491442        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    497448        // THE SYSTEM IS NOW COMPLETELY STOPPED
    498449
    499         // Disable preemption
    500         kernel_stop_preemption();
    501 
    502450        // Destroy the system processor and its context in reverse order of construction
    503451        // These were manually constructed so we need manually destroy them
     
    509457        ^(mainThread){};
    510458
    511         LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");
     459        LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");   
    512460}
    513461
     
    519467        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    520468        // the globalAbort flag is true.
    521         lock( &kernel_abort_lock DEBUG_CTX2 );
     469        lock( &kernel_abort_lock );
    522470
    523471        // first task to abort ?
     
    525473                kernel_abort_called = true;
    526474                unlock( &kernel_abort_lock );
    527         }
     475        } 
    528476        else {
    529477                unlock( &kernel_abort_lock );
    530 
     478               
    531479                sigset_t mask;
    532480                sigemptyset( &mask );
     
    534482                sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    535483                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    536                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    537         }
    538 
    539         return this_thread;
     484                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it             
     485        }
     486
     487        return this_thread();
    540488}
    541489
     
    546494        __lib_debug_write( STDERR_FILENO, abort_text, len );
    547495
    548         if ( thrd != this_coroutine ) {
    549                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
     496        if ( thrd != this_coroutine() ) {
     497                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine()->name, this_coroutine() );
    550498                __lib_debug_write( STDERR_FILENO, abort_text, len );
    551         }
     499        } 
    552500        else {
    553501                __lib_debug_write( STDERR_FILENO, ".\n", 2 );
     
    557505extern "C" {
    558506        void __lib_debug_acquire() {
    559                 lock( &kernel_debug_lock DEBUG_CTX2 );
     507                lock(&kernel_debug_lock);
    560508        }
    561509
    562510        void __lib_debug_release() {
    563                 unlock( &kernel_debug_lock );
     511                unlock(&kernel_debug_lock);
    564512        }
    565513}
     
    577525}
    578526
    579 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {
     527bool try_lock( spinlock * this ) {
    580528        return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;
    581529}
    582530
    583 void lock( spinlock * this DEBUG_CTX_PARAM2 ) {
     531void lock( spinlock * this ) {
    584532        for ( unsigned int i = 1;; i += 1 ) {
    585                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
    586         }
    587         LIB_DEBUG_DO(
    588                 this->prev_name = caller;
    589                 this->prev_thrd = this_thread;
    590         )
    591 }
    592 
    593 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) {
    594         for ( unsigned int i = 1;; i += 1 ) {
    595                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
    596                 yield();
    597         }
    598         LIB_DEBUG_DO(
    599                 this->prev_name = caller;
    600                 this->prev_thrd = this_thread;
    601         )
    602 }
    603 
     533                if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break;
     534        }
     535}
    604536
    605537void unlock( spinlock * this ) {
     
    615547
    616548void wait( signal_once * this ) {
    617         lock( &this->lock DEBUG_CTX2 );
     549        lock( &this->lock );
    618550        if( !this->cond ) {
    619                 append( &this->blocked, (thread_desc*)this_thread );
    620                 BlockInternal( &this->lock );
    621         }
    622         else {
    623                 unlock( &this->lock );
    624         }
     551                append( &this->blocked, this_thread() );
     552                ScheduleInternal( &this->lock );
     553                lock( &this->lock );
     554        }
     555        unlock( &this->lock );
    625556}
    626557
    627558void signal( signal_once * this ) {
    628         lock( &this->lock DEBUG_CTX2 );
     559        lock( &this->lock );
    629560        {
    630561                this->cond = true;
    631562
    632                 disable_interrupts();
    633563                thread_desc * it;
    634564                while( it = pop_head( &this->blocked) ) {
    635565                        ScheduleThread( it );
    636566                }
    637                 enable_interrupts( DEBUG_CTX );
    638567        }
    639568        unlock( &this->lock );
     
    661590                }
    662591                head->next = NULL;
    663         }
     592        }       
    664593        return head;
    665594}
     
    680609                this->top = top->next;
    681610                top->next = NULL;
    682         }
     611        }       
    683612        return top;
    684613}
  • src/libcfa/concurrency/kernel_private.h

    r0614d14 r1ce2189  
    1818#define KERNEL_PRIVATE_H
    1919
    20 #include "libhdr.h"
    21 
    2220#include "kernel"
    2321#include "thread"
     
    2523#include "alarm.h"
    2624
     25#include "libhdr.h"
    2726
    2827//-----------------------------------------------------------------------------
    2928// Scheduler
    30 
    31 extern "C" {
    32         void disable_interrupts();
    33         void enable_interrupts_noRF();
    34         void enable_interrupts( DEBUG_CTX_PARAM );
    35 }
    36 
    3729void ScheduleThread( thread_desc * );
    38 static inline void WakeThread( thread_desc * thrd ) {
    39         if( !thrd ) return;
    40 
    41         disable_interrupts();
    42         ScheduleThread( thrd );
    43         enable_interrupts( DEBUG_CTX );
    44 }
    4530thread_desc * nextThread(cluster * this);
    4631
    47 void BlockInternal(void);
    48 void BlockInternal(spinlock * lock);
    49 void BlockInternal(thread_desc * thrd);
    50 void BlockInternal(spinlock * lock, thread_desc * thrd);
    51 void BlockInternal(spinlock ** locks, unsigned short count);
    52 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);
    5338
    5439//-----------------------------------------------------------------------------
     
    7560extern cluster * systemCluster;
    7661extern system_proc_t * systemProcessor;
    77 extern volatile thread_local processor * this_processor;
    78 extern volatile thread_local coroutine_desc * this_coroutine;
    79 extern volatile thread_local thread_desc * this_thread;
    80 extern volatile thread_local unsigned short disable_preempt_count;
     62extern thread_local processor * this_processor;
     63
     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        }
     81}
    8182
    8283//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor

    r0614d14 r1ce2189  
    2626static inline void ?{}(monitor_desc * this) {
    2727        this->owner = NULL;
     28        this->stack_owner = NULL;
    2829        this->recursion = 0;
    2930}
  • src/libcfa/concurrency/monitor.c

    r0614d14 r1ce2189  
    1919#include <stdlib>
    2020
     21#include "kernel_private.h"
    2122#include "libhdr.h"
    22 #include "kernel_private.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "C" {
    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);
     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);
    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                         BlockInternal( &this->lock );
    66 
    67                         //BlockInternal will unlock spinlock, no need to unlock ourselves
    68                         return;
     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; 
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      TODO
    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 );
     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 );
    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                 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                 //We can now let other threads in safely
    127                 unlock( &this->lock );
    128 
    129                 //We need to wake-up the thread
    130                 if( new_owner) ScheduleThread( new_owner );
     101                ScheduleThread( new_owner );
    131102        }
    132103}
     
    150121        enter( this->m, this->count );
    151122
    152         this->prev_mntrs = this_thread->current_monitors;
    153         this->prev_count = this_thread->current_monitor_count;
    154 
    155         this_thread->current_monitors      = m;
    156         this_thread->current_monitor_count = count;
     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;
    157128}
    158129
     
    160131        leave( this->m, this->count );
    161132
    162         this_thread->current_monitors      = this->prev_mntrs;
    163         this_thread->current_monitor_count = this->prev_count;
     133        this_thread()->current_monitors      = this->prev_mntrs;
     134        this_thread()->current_monitor_count = this->prev_count;
    164135}
    165136
     
    188159// Internal scheduling
    189160void wait( condition * this, uintptr_t user_info = 0 ) {
    190         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
     161        LIB_DEBUG_PRINT_SAFE("Waiting\n");
    191162
    192163        brand_condition( this );
     
    199170        unsigned short count = this->monitor_count;
    200171        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    201         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    202 
    203         // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    204 
    205         __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
     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 };
    206177
    207178        __condition_criterion_t criteria[count];
    208179        for(int i = 0; i < count; i++) {
    209180                (&criteria[i]){ this->monitors[i], &waiter };
    210                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     181                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    211182        }
    212183
     
    230201        }
    231202
    232         // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     203        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    233204        for(int i = 0; i < thread_count; i++) {
    234                 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    235         }
    236         // LIB_DEBUG_PRINT_SAFE("\n");
     205                LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     206        }
     207        LIB_DEBUG_PRINT_SAFE("\n");
    237208
    238209        // Everything is ready to go to sleep
    239         BlockInternal( locks, count, threads, thread_count );
     210        ScheduleInternal( locks, count, threads, thread_count );
    240211
    241212
     
    251222bool signal( condition * this ) {
    252223        if( is_empty( this ) ) {
    253                 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     224                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    254225                return false;
    255226        }
     
    260231
    261232        unsigned short count = this->monitor_count;
    262 
     233       
    263234        //Some more checking in debug
    264235        LIB_DEBUG_DO(
    265                 thread_desc * this_thrd = this_thread;
     236                thread_desc * this_thrd = this_thread();
    266237                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    267238                        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 );
     
    277248        //Lock all the monitors
    278249        lock_all( this->monitors, NULL, count );
    279         // LIB_DEBUG_PRINT_SAFE("Signalling");
     250        LIB_DEBUG_PRINT_SAFE("Signalling");
    280251
    281252        //Pop the head of the waiting queue
     
    285256        for(int i = 0; i < count; i++) {
    286257                __condition_criterion_t * crit = &node->criteria[i];
    287                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     258                LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    288259                assert( !crit->ready );
    289260                push( &crit->target->signal_stack, crit );
    290261        }
    291262
    292         // LIB_DEBUG_PRINT_SAFE("\n");
     263        LIB_DEBUG_PRINT_SAFE("\n");
    293264
    294265        //Release
     
    310281        unsigned short count = this->monitor_count;
    311282        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    312         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
    313284
    314285        lock_all( this->monitors, locks, count );
    315286
    316287        //create creteria
    317         __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
     288        __condition_node_t waiter = { this_thread(), count, 0 };
    318289
    319290        __condition_criterion_t criteria[count];
    320291        for(int i = 0; i < count; i++) {
    321292                (&criteria[i]){ this->monitors[i], &waiter };
    322                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     293                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    323294                push( &criteria[i].target->signal_stack, &criteria[i] );
    324295        }
     
    338309
    339310        //Everything is ready to go to sleep
    340         BlockInternal( locks, count, &signallee, 1 );
     311        ScheduleInternal( locks, count, &signallee, 1 );
    341312
    342313
     
    354325
    355326uintptr_t front( condition * this ) {
    356         verifyf( !is_empty(this),
     327        verifyf( !is_empty(this), 
    357328                "Attempt to access user data on an empty condition.\n"
    358329                "Possible cause is not checking if the condition is empty before reading stored data."
     
    364335// Internal scheduling
    365336void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    366         // thread_desc * this = this_thread;
     337        // thread_desc * this = this_thread();
    367338
    368339        // unsigned short count = this->current_monitor_count;
    369340        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    370         // 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
    371342
    372343        // lock_all( this->current_monitors, locks, count );
     
    377348
    378349        // // // Everything is ready to go to sleep
    379         // // BlockInternal( locks, count, threads, thread_count );
     350        // // ScheduleInternal( locks, count, threads, thread_count );
    380351
    381352
     
    422393static inline void lock_all( spinlock ** locks, unsigned short count ) {
    423394        for( int i = 0; i < count; i++ ) {
    424                 lock_yield( locks[i] DEBUG_CTX2 );
     395                lock( locks[i] );
    425396        }
    426397}
     
    429400        for( int i = 0; i < count; i++ ) {
    430401                spinlock * l = &source[i]->lock;
    431                 lock_yield( l DEBUG_CTX2 );
     402                lock( l );
    432403                if(locks) locks[i] = l;
    433404        }
     
    472443        for(    int i = 0; i < count; i++ ) {
    473444
    474                 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     445                LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    475446                if( &criteria[i] == target ) {
    476447                        criteria[i].ready = true;
    477                         // LIB_DEBUG_PRINT_SAFE( "True\n" );
     448                        LIB_DEBUG_PRINT_SAFE( "True\n" );
    478449                }
    479450
     
    481452        }
    482453
    483         // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     454        LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    484455        return ready2run ? node->waiting_thread : NULL;
    485456}
    486457
    487458static inline void brand_condition( condition * this ) {
    488         thread_desc * thrd = this_thread;
     459        thread_desc * thrd = this_thread();
    489460        if( !this->monitors ) {
    490                 // LIB_DEBUG_PRINT_SAFE("Branding\n");
     461                LIB_DEBUG_PRINT_SAFE("Branding\n");
    491462                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    492463                this->monitor_count = thrd->current_monitor_count;
  • src/libcfa/concurrency/preemption.c

    r0614d14 r1ce2189  
    1515//
    1616
    17 #include "libhdr.h"
    1817#include "preemption.h"
    1918
    2019extern "C" {
    21 #include <errno.h>
    22 #include <execinfo.h>
    23 #define __USE_GNU
    2420#include <signal.h>
    25 #undef __USE_GNU
    26 #include <stdio.h>
    27 #include <string.h>
    28 #include <unistd.h>
    2921}
    3022
    31 
    32 #ifdef __USE_STREAM__
    33 #include "fstream"
    34 #endif
    35 
    36 #define __CFA_DEFAULT_PREEMPTION__ 10000
     23#define __CFA_DEFAULT_PREEMPTION__ 10
    3724
    3825__attribute__((weak)) unsigned int default_preemption() {
     
    4027}
    4128
    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 
    4529static void preempt( processor   * this );
    4630static void timeout( thread_desc * this );
    47 
    48 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
    49 void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    50 void sigHandler_segv     ( __CFA_SIGPARMS__ );
    51 void sigHandler_abort    ( __CFA_SIGPARMS__ );
    52 
    53 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    54 LIB_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 
    6231
    6332//=============================================================================================
     
    6534//=============================================================================================
    6635
     36void kernel_start_preemption() {
     37
     38}
     39
    6740void tick_preemption() {
    68         // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );
    69 
    7041        alarm_list_t * alarms = &systemProcessor->alarms;
    7142        __cfa_time_t currtime = __kernel_get_time();
    7243        while( alarms->head && alarms->head->alarm < currtime ) {
    7344                alarm_node_t * node = pop(alarms);
    74                 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node );
    75 
    7645                if( node->kernel_alarm ) {
    7746                        preempt( node->proc );
     
    8150                }
    8251
    83                 verify( validate( alarms ) );
    84 
    8552                if( node->period > 0 ) {
    86                         node->alarm = currtime + node->period;
     53                        node->alarm += node->period;
    8754                        insert( alarms, node );
    8855                }
     
    9562                __kernel_set_timer( alarms->head->alarm - currtime );
    9663        }
    97 
    98         verify( validate( alarms ) );
    99         // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" );
    10064}
    10165
    10266void update_preemption( processor * this, __cfa_time_t duration ) {
    103         LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration );
    104 
     67        //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
    10568        alarm_node_t * alarm = this->preemption_alarm;
    106         duration *= 1000;
    10769
    10870        // Alarms need to be enabled
     
    12789}
    12890
     91void ?{}( preemption_scope * this, processor * proc ) {
     92        (&this->alarm){ proc };
     93        this->proc = proc;
     94        this->proc->preemption_alarm = &this->alarm;
     95        update_preemption( this->proc, this->proc->preemption );
     96}
     97
     98void ^?{}( preemption_scope * this ) {
     99        update_preemption( this->proc, 0 );
     100}
     101
    129102//=============================================================================================
    130 // Kernel Signal Tools
     103// Kernel Signal logic
    131104//=============================================================================================
    132105
    133 LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
    134 
    135 extern "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 
    161 static 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 
    171 static 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 
    181106static inline bool preemption_ready() {
    182         return disable_preempt_count == 0;
     107        return this_processor->disable_preempt_count == 0;
    183108}
    184109
     
    191116}
    192117
     118void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
     119        if( preemption_ready() ) {
     120                ScheduleInternal( this_processor->current_thread );
     121        }
     122        else {
     123                defer_ctxSwitch();
     124        }
     125}
     126
     127void sigHandler_alarm( __attribute__((unused)) int sig ) {
     128        if( try_lock( &systemProcessor->alarm_lock ) ) {
     129                tick_preemption();
     130                unlock( &systemProcessor->alarm_lock );
     131        }
     132        else {
     133                defer_alarm();
     134        }
     135}
     136
    193137static void preempt( processor * this ) {
    194138        pthread_kill( this->kernel_thread, SIGUSR1 );
     
    198142        //TODO : implement waking threads
    199143}
    200 
    201 //=============================================================================================
    202 // Kernel Signal Startup/Shutdown logic
    203 //=============================================================================================
    204 
    205 static pthread_t alarm_thread;
    206 void * alarm_loop( __attribute__((unused)) void * args );
    207 
    208 void 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 
    219 void 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 
    229 void ?{}( preemption_scope * this, processor * proc ) {
    230         (&this->alarm){ proc };
    231         this->proc = proc;
    232         this->proc->preemption_alarm = &this->alarm;
    233         update_preemption( this->proc, this->proc->preemption );
    234 }
    235 
    236 void ^?{}( preemption_scope * this ) {
    237         disable_interrupts();
    238 
    239         update_preemption( this->proc, 0 );
    240 }
    241 
    242 //=============================================================================================
    243 // Kernel Signal Handlers
    244 //=============================================================================================
    245 
    246 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    247         LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
    248         if( preemption_ready() ) {
    249                 signal_unblock( SIGUSR1 );
    250                 BlockInternal( (thread_desc*)this_thread );
    251         }
    252         else {
    253                 defer_ctxSwitch();
    254         }
    255 }
    256 
    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 
    279 void * 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 
    316 static 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 
    331 typedef void (*sa_handler_t)(int);
    332 
    333 static 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 
    353 LIB_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

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

    r0614d14 r1ce2189  
    2828}
    2929
    30 extern volatile thread_local processor * this_processor;
     30extern 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;
     73        thrd_c->last = this_coroutine();
     74        this_processor->current_coroutine = thrd_c;
    7475
    75         // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     76        LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    7677
    77         disable_interrupts();
    7878        create_stack(&thrd_c->stack, thrd_c->stack.size);
    79         this_coroutine = thrd_c;
    8079        CtxStart(this, CtxInvokeThread);
    81         assert( thrd_c->last->stack.context );
    8280        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8381
    8482        ScheduleThread(thrd_h);
    85         enable_interrupts( DEBUG_CTX );
    8683}
    8784
    8885void yield( void ) {
    89         BlockInternal( (thread_desc *)this_thread );
     86        ScheduleInternal( this_processor->current_thread );
    9087}
    9188
     
    9895void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9996        // set state of current coroutine to inactive
    100         src->state = src->state == Halted ? Halted : Inactive;
     97        src->state = Inactive;
    10198        dst->state = Active;
    10299
     
    106103        // set new coroutine that the processor is executing
    107104        // and context switch to it
    108         this_coroutine = dst;
    109         assert( src->stack.context );
     105        this_processor->current_coroutine = dst;
    110106        CtxSwitch( src->stack.context, dst->stack.context );
    111         this_coroutine = src;
     107        this_processor->current_coroutine = src;
    112108
    113109        // set state of new coroutine to active
    114         dst->state = dst->state == Halted ? Halted : Inactive;
     110        dst->state = Inactive;
    115111        src->state = Active;
    116112}
  • src/libcfa/libhdr/libalign.h

    r0614d14 r1ce2189  
    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>
    3635
    37 // Minimum size used to align memory boundaries for memory allocations.
     36// Minimum size used to align memory boundaries for memory allocations. 
    3837#define libAlign() (sizeof(double))
    3938
  • src/libcfa/libhdr/libdebug.h

    r0614d14 r1ce2189  
    1818
    1919#ifdef __CFA_DEBUG__
    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
     20        #define LIB_DEBUG_DO(x) x
     21        #define LIB_NO_DEBUG_DO(x) ((void)0)
    2622#else
    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
     23        #define LIB_DEBUG_DO(x) ((void)0)
     24        #define LIB_NO_DEBUG_DO(x) x     
    3325#endif
    3426
     
    5951
    6052#ifdef __CFA_DEBUG_PRINT__
    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 );
     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__)
    6959#else
    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)
     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)
    7866#endif
    7967
  • src/tests/sched-int-block.c

    r0614d14 r1ce2189  
    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
Note: See TracChangeset for help on using the changeset viewer.