Ignore:
Timestamp:
Jul 6, 2017, 4:18:43 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
955d27e9
Parents:
b877fa8
Message:

Removed signal_once type, use semaphore instead

Location:
src/libcfa/concurrency
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/kernel

    rb877fa8 rbdeba0b  
    3333void unlock    ( spinlock * );
    3434
    35 struct signal_once {
    36         volatile bool cond;
    37         struct spinlock lock;
    38         struct __thread_queue_t blocked;
     35struct semaphore {
     36        spinlock lock;
     37        int count;
     38        __thread_queue_t waiting;
    3939};
    4040
    41 void ?{}(signal_once * this);
    42 void ^?{}(signal_once * this);
     41void  ?{}(semaphore * this, int count = 1);
     42void ^?{}(semaphore * this);
     43void P(semaphore * this);
     44void V(semaphore * this);
    4345
    44 void wait( signal_once * );
    45 void signal( signal_once * );
    4646
    4747//-----------------------------------------------------------------------------
     
    8181        pthread_t kernel_thread;
    8282
    83         signal_once terminated;
     83        semaphore terminated;
    8484        volatile bool is_terminated;
    8585
  • src/libcfa/concurrency/kernel.c

    rb877fa8 rbdeba0b  
    129129void ?{}(processor * this, cluster * cltr) {
    130130        this->cltr = cltr;
    131         (&this->terminated){};
     131        (&this->terminated){ 0 };
    132132        this->is_terminated = false;
    133133        this->preemption_alarm = NULL;
     
    140140void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    141141        this->cltr = cltr;
    142         (&this->terminated){};
     142        (&this->terminated){ 0 };
    143143        this->is_terminated = false;
    144144        this->preemption_alarm = NULL;
     
    168168                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
    169169                this->is_terminated = true;
    170                 wait( &this->terminated );
     170                P( &this->terminated );
     171                pthread_join( this->kernel_thread, NULL );
    171172        }
    172173}
     
    223224        }
    224225
    225         signal( &this->terminated );
     226        V( &this->terminated );
     227
    226228        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
    227229}
     
    607609}
    608610
    609 void ?{}( signal_once * this ) {
    610         this->cond = false;
    611 }
    612 void ^?{}( signal_once * this ) {
    613 
    614 }
    615 
    616 void wait( signal_once * this ) {
     611void  ?{}( semaphore * this, int count = 1 ) {
     612        (&this->lock){};
     613        this->count = count;
     614        (&this->waiting){};
     615}
     616void ^?{}(semaphore * this) {}
     617
     618void P(semaphore * this) {
    617619        lock( &this->lock DEBUG_CTX2 );
    618         if( !this->cond ) {
    619                 append( &this->blocked, (thread_desc*)this_thread );
     620        this->count -= 1;
     621        if ( this->count < 0 ) {
     622                // queue current task
     623                append( &this->waiting, (thread_desc *)this_thread );
     624
     625                // atomically release spin lock and block
    620626                BlockInternal( &this->lock );
    621627        }
    622628        else {
    623                 unlock( &this->lock );
    624         }
    625 }
    626 
    627 void signal( signal_once * this ) {
     629            unlock( &this->lock );
     630        }
     631}
     632
     633void V(semaphore * this) {
     634        thread_desc * thrd = NULL;
    628635        lock( &this->lock DEBUG_CTX2 );
    629         {
    630                 this->cond = true;
    631 
    632                 disable_interrupts();
    633                 thread_desc * it;
    634                 while( it = pop_head( &this->blocked) ) {
    635                         ScheduleThread( it );
    636                 }
    637                 enable_interrupts( DEBUG_CTX );
    638         }
     636        this->count += 1;
     637        if ( this->count <= 0 ) {
     638                // remove task at head of waiting list
     639                thrd = pop_head( &this->waiting );
     640        }
     641
    639642        unlock( &this->lock );
     643
     644        // make new owner
     645        WakeThread( thrd );
    640646}
    641647
Note: See TracChangeset for help on using the changeset viewer.