Changes in / [da6d4566:168c007]


Ignore:
Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    rda6d4566 r168c007  
    331331                        ),
    332332                        new ListInit(
    333                                 map_range < std::list<Initializer*> > ( args, [this](DeclarationWithType * var ){
    334                                         Type * type = var->get_type()->clone();
    335                                         type->set_mutex( false );
     333                                map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){
    336334                                        return new SingleInit( new UntypedExpr(
    337335                                                new NameExpr( "get_monitor" ),
    338                                                 {  new CastExpr( new VariableExpr( var ), type ) }
     336                                                {  new VariableExpr( var ) }
    339337                                        ) );
    340338                                })
  • src/libcfa/concurrency/invoke.c

    rda6d4566 r168c007  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_monitor_desc( struct monitor_desc * this );
     31extern void __thread_signal_termination(struct thread_desc*);
    3232
    3333void CtxInvokeCoroutine(
     
    6565      struct thread_desc* thrd = get_thread( this );
    6666      struct coroutine_desc* cor = &thrd->cor;
    67       struct monitor_desc* mon = &thrd->mon;
    6867      cor->state = Active;
    6968
     
    7170      main( this );
    7271
    73       __leave_monitor_desc( mon );
     72      __thread_signal_termination(thrd);
    7473
    7574      //Final suspend, should never return
  • src/libcfa/concurrency/invoke.h

    rda6d4566 r168c007  
    3838      };
    3939
     40      struct signal_once {
     41            volatile bool condition;
     42            struct spinlock lock;
     43            struct simple_thread_list blocked;
     44      };
     45
    4046      #ifdef __CFORALL__
    4147      extern "Cforall" {
     
    4652            void ?{}(spinlock * this);
    4753            void ^?{}(spinlock * this);
     54
     55            void ?{}(signal_once * this);
     56            void ^?{}(signal_once * this);
    4857      }
    4958      #endif
     
    7079      };
    7180
    72       struct monitor_desc {
    73             struct spinlock lock;
    74             struct thread_desc * owner;
    75             struct simple_thread_list entry_queue;
    76             unsigned int recursion;
    77       };
    78 
    7981      struct thread_desc {
    80             struct coroutine_desc cor;          // coroutine body used to store context
    81             struct monitor_desc mon;            // monitor body used for mutual exclusion
     82            struct coroutine_desc cor;            // coroutine body used to store context
     83            struct signal_once terminated;      // indicate if execuation state is not halted
    8284            struct thread_desc * next;          // instrusive link field for threads
    8385      };
  • src/libcfa/concurrency/kernel

    rda6d4566 r168c007  
    3030void lock( spinlock * );
    3131void unlock( spinlock * );
    32 
    33 struct signal_once {
    34         volatile bool condition;
    35         struct spinlock lock;
    36         struct simple_thread_list blocked;
    37 };
    38 
    39 void ?{}(signal_once * this);
    40 void ^?{}(signal_once * this);
    4132
    4233void wait( signal_once * );
  • src/libcfa/concurrency/monitor

    rda6d4566 r168c007  
    2121#include "invoke.h"
    2222#include "stdlib"
     23
     24struct monitor_desc {
     25        spinlock lock;
     26        thread_desc * owner;
     27        simple_thread_list entry_queue;
     28        unsigned int recursion;
     29};
    2330
    2431static inline void ?{}(monitor_desc * this) {
  • src/libcfa/concurrency/monitor.c

    rda6d4566 r168c007  
    1919#include "kernel_private.h"
    2020
    21 extern "C" {
    22         void __enter_monitor_desc(monitor_desc * this) {
    23                 lock( &this->lock );
    24                 thread_desc * thrd = this_thread();
     21void enter(monitor_desc * this) {
     22        lock( &this->lock );
     23        thread_desc * thrd = this_thread();
    2524
    26                 if( !this->owner ) {
    27                         //No one has the monitor, just take it
    28                         this->owner = thrd;
    29                         this->recursion = 1;
    30                 }
    31                 else if( this->owner == thrd) {
    32                         //We already have the monitor, just not how many times we took it
    33                         assert( this->recursion > 0 );
    34                         this->recursion += 1;
    35                 }
    36                 else {
    37                         //Some one else has the monitor, wait in line for it
    38                         append( &this->entry_queue, thrd );
    39                         ScheduleInternal( &this->lock );
     25        if( !this->owner ) {
     26                //No one has the monitor, just take it
     27                this->owner = thrd;
     28                this->recursion = 1;
     29        }
     30        else if( this->owner == thrd) {
     31                //We already have the monitor, just not how many times we took it
     32                assert( this->recursion > 0 );
     33                this->recursion += 1;
     34        }
     35        else {
     36                //Some one else has the monitor, wait in line for it
     37                append( &this->entry_queue, thrd );
     38                ScheduleInternal( &this->lock );
    4039
    41                         //ScheduleInternal will unlock spinlock, no need to unlock ourselves
    42                         return;
    43                 }
    44 
    45                 unlock( &this->lock );
     40                //ScheduleInternal will unlock spinlock, no need to unlock ourselves
     41                return;
    4642        }
    4743
    48         void __leave_monitor_desc(monitor_desc * this) {
    49                 lock( &this->lock );
     44        unlock( &this->lock );
     45}
    5046
    51                 thread_desc * thrd = this_thread();
    52                 assert( thrd == this->owner );
     47void leave(monitor_desc * this) {
     48        lock( &this->lock );
    5349
    54                 //Leaving a recursion level, decrement the counter
    55                 this->recursion -= 1;
     50        thread_desc * thrd = this_thread();
     51        assert( thrd == this->owner );
    5652
    57                 //If we left the last level of recursion it means we are changing who owns the monitor
    58                 thread_desc * new_owner = 0;
    59                 if( this->recursion == 0) {
    60                         //Get the next thread in the list
    61                         new_owner = this->owner = pop_head( &this->entry_queue );
     53        //Leaving a recursion level, decrement the counter
     54        this->recursion -= 1;
    6255
    63                         //We are passing the monitor to someone else, which means recursion level is not 0
    64                         this->recursion = new_owner ? 1 : 0;
    65                 }       
     56        //If we left the last level of recursion it means we are changing who owns the monitor
     57        thread_desc * new_owner = 0;
     58        if( this->recursion == 0) {
     59                //Get the next thread in the list
     60                new_owner = this->owner = pop_head( &this->entry_queue );
    6661
    67                 unlock( &this->lock );
     62                //We are passing the monitor to someone else, which means recursion level is not 0
     63                this->recursion = new_owner ? 1 : 0;
     64        }       
    6865
    69                 //If we have a new owner, we need to wake-up the thread
    70                 if( new_owner ) {
    71                         ScheduleThread( new_owner );
    72                 }
     66        unlock( &this->lock );
     67
     68        //If we have a new owner, we need to wake-up the thread
     69        if( new_owner ) {
     70                ScheduleThread( new_owner );
    7371        }
    7472}
     
    7674void enter(monitor_desc ** monitors, int count) {
    7775        for(int i = 0; i < count; i++) {
    78                 __enter_monitor_desc( monitors[i] );
     76                enter( monitors[i] );
    7977        }
    8078}
     
    8280void leave(monitor_desc ** monitors, int count) {
    8381        for(int i = count - 1; i >= 0; i--) {
    84                 __leave_monitor_desc( monitors[i] );
     82                leave( monitors[i] );
    8583        }
    8684}
  • src/libcfa/concurrency/thread

    rda6d4566 r168c007  
    2222
    2323#include "coroutine"
    24 #include "monitor"
    2524
    2625//-----------------------------------------------------------------------------
     
    2928// Anything that is resumed is a coroutine.
    3029trait is_thread(dtype T) {
    31       void ^?{}(T* mutex this);
     30      void ^?{}(T* this);
    3231      void main(T* this);
    3332      thread_desc* get_thread(T* this);
     
    4140}
    4241
    43 forall( dtype T | is_thread(T) )
    44 static inline monitor_desc* get_monitor(T * this) {
    45         return &get_thread(this)->mon;
    46 }
    47 
    48 static inline coroutine_desc* get_coroutine(thread_desc * this) {
     42static inline coroutine_desc* get_coroutine(thread_desc* this) {
    4943        return &this->cor;
    50 }
    51 
    52 static inline monitor_desc* get_monitor(thread_desc * this) {
    53         return &this->mon;
    5444}
    5545
  • src/libcfa/concurrency/thread.c

    rda6d4566 r168c007  
    3535void start( T* this );
    3636
     37forall( dtype T | is_thread(T) )
     38void stop( T* this );
     39
    3740//-----------------------------------------------------------------------------
    3841// Thread ctors and dtors
     
    4144        (&this->cor){};
    4245        this->cor.name = "Anonymous Coroutine";
    43         this->mon.owner = this;
    44         this->mon.recursion = 1;
     46        (&this->terminated){};
    4547        this->next = NULL;
    4648}
     
    6466forall( dtype T | sized(T) | is_thread(T) )
    6567void ^?{}( scoped(T)* this ) {
     68        stop(&this->handle);
    6669        ^(&this->handle){};
    6770}
     
    8386
    8487        ScheduleThread(thrd_h);
     88}
     89
     90forall( dtype T | is_thread(T) )
     91void stop( T* this ) {
     92        wait( & get_thread(this)->terminated );
    8593}
    8694
     
    108116}
    109117
     118// C Helper to signal the termination of a thread_desc
     119// Used in invoke.c
     120extern "C" {
     121        void __thread_signal_termination( thread_desc * this ) {
     122                this->cor.state = Halted;
     123                LIB_DEBUG_PRINTF("Thread end : %p\n", this);
     124                signal( &this->terminated );   
     125        }
     126}
     127
    110128// Local Variables: //
    111129// mode: c //
  • src/tests/monitor.c

    rda6d4566 r168c007  
    3636
    3737void ?{}( MyThread * this ) {}
    38 void ^?{}( MyThread * mutex this ) {}
    3938
    4039void main( MyThread* this ) {
    41         for(int i = 0; i < 1_000_000; i++) {
     40        for(int i = 0; i < 1000000; i++) {
    4241                increment( &global );
    4342        }
  • src/tests/multi-monitor.c

    rda6d4566 r168c007  
    3131}
    3232
    33 void ^?{}( MyThread * mutex this ) {}
    34 
    3533void main( MyThread* this ) {
    3634        for(int i = 0; i < 1000000; i++) {
  • src/tests/thread.c

    rda6d4566 r168c007  
    1212void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
    1313void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
    14 
    15 void ^?{}( First  * mutex this ) {}
    16 void ^?{}( Second * mutex this ) {}
    1714
    1815void main(First* this) {
Note: See TracChangeset for help on using the changeset viewer.