Changes in / [121ac13:9f4524b]


Ignore:
Location:
src
Files:
1 added
19 edited

Legend:

Unmodified
Added
Removed
  • src/benchmark/Makefile.am

    r121ac13 r9f4524b  
    2727
    2828noinst_PROGRAMS =
    29 
    30 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
    3129
    3230bench$(EXEEXT) :
     
    6563ctxswitch-pthread$(EXEEXT):
    6664        @BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     65
     66## =========================================================================================================
     67creation$(EXEEXT) :\
     68        creation-pthread.run            \
     69        creation-cfa_coroutine.run      \
     70        creation-cfa_thread.run         \
     71        creation-upp_coroutine.run      \
     72        creation-upp_thread.run
     73
     74creation-cfa_coroutine$(EXEEXT):
     75        ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     76
     77creation-cfa_thread$(EXEEXT):
     78        ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     79
     80creation-upp_coroutine$(EXEEXT):
     81        u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     82
     83creation-upp_thread$(EXEEXT):
     84        u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     85
     86creation-pthread$(EXEEXT):
     87        @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    6788
    6889## =========================================================================================================
     
    132153
    133154## =========================================================================================================
    134 creation$(EXEEXT) :\
    135         creation-pthread.run            \
    136         creation-cfa_coroutine.run      \
    137         creation-cfa_thread.run         \
    138         creation-upp_coroutine.run      \
    139         creation-upp_thread.run
    140 
    141 creation-cfa_coroutine$(EXEEXT):
    142         ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    143 
    144 creation-cfa_thread$(EXEEXT):
    145         ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    146 
    147 creation-upp_coroutine$(EXEEXT):
    148         u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    149 
    150 creation-upp_thread$(EXEEXT):
    151         u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    152 
    153 creation-pthread$(EXEEXT):
    154         @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    155 
    156 ## =========================================================================================================
    157155
    158156%.run : %$(EXEEXT) ${REPEAT}
  • src/benchmark/Makefile.in

    r121ac13 r9f4524b  
    444444.NOTPARALLEL:
    445445
    446 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
    447 
    448446bench$(EXEEXT) :
    449447        @for ccflags in "-debug" "-nodebug"; do \
     
    481479        @BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    482480
     481creation$(EXEEXT) :\
     482        creation-pthread.run            \
     483        creation-cfa_coroutine.run      \
     484        creation-cfa_thread.run         \
     485        creation-upp_coroutine.run      \
     486        creation-upp_thread.run
     487
     488creation-cfa_coroutine$(EXEEXT):
     489        ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     490
     491creation-cfa_thread$(EXEEXT):
     492        ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     493
     494creation-upp_coroutine$(EXEEXT):
     495        u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     496
     497creation-upp_thread$(EXEEXT):
     498        u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     499
     500creation-pthread$(EXEEXT):
     501        @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     502
    483503mutex$(EXEEXT) :\
    484504        mutex-function.run      \
     
    542562waitfor-cfa4$(EXEEXT):
    543563        ${CC}        schedext/cfa4.c     -DBENCH_N=500000      -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    544 
    545 creation$(EXEEXT) :\
    546         creation-pthread.run            \
    547         creation-cfa_coroutine.run      \
    548         creation-cfa_thread.run         \
    549         creation-upp_coroutine.run      \
    550         creation-upp_thread.run
    551 
    552 creation-cfa_coroutine$(EXEEXT):
    553         ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    554 
    555 creation-cfa_thread$(EXEEXT):
    556         ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    557 
    558 creation-upp_coroutine$(EXEEXT):
    559         u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    560 
    561 creation-upp_thread$(EXEEXT):
    562         u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    563 
    564 creation-pthread$(EXEEXT):
    565         @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    566564
    567565%.run : %$(EXEEXT) ${REPEAT}
  • src/benchmark/csv-data.c

    r121ac13 r9f4524b  
    111111        StartTime = Time();
    112112        for( int i = 0;; i++ ) {
    113                 signal(cond1a);
    114                 if( i > N ) break;
    115                 wait(cond1b);
     113                signal(&cond1a);
     114                if( i > N ) break;
     115                wait(&cond1b);
    116116        }
    117117        EndTime = Time();
     
    122122void side1B( mon_t & mutex a ) {
    123123        for( int i = 0;; i++ ) {
    124                 signal(cond1b);
    125                 if( i > N ) break;
    126                 wait(cond1a);
     124                signal(&cond1b);
     125                if( i > N ) break;
     126                wait(&cond1a);
    127127        }
    128128}
     
    159159        StartTime = Time();
    160160        for( int i = 0;; i++ ) {
    161                 signal(cond2a);
    162                 if( i > N ) break;
    163                 wait(cond2b);
     161                signal(&cond2a);
     162                if( i > N ) break;
     163                wait(&cond2b);
    164164        }
    165165        EndTime = Time();
     
    170170void side2B( mon_t & mutex a, mon_t & mutex b ) {
    171171        for( int i = 0;; i++ ) {
    172                 signal(cond2b);
    173                 if( i > N ) break;
    174                 wait(cond2a);
     172                signal(&cond2b);
     173                if( i > N ) break;
     174                wait(&cond2a);
    175175        }
    176176}
  • src/benchmark/schedint/cfa1.c

    r121ac13 r9f4524b  
    1515
    1616void __attribute__((noinline)) call( M & mutex a1 ) {
    17         signal(c);
     17        signal(&c);
    1818}
    1919
     
    2222        BENCH(
    2323                for (size_t i = 0; i < n; i++) {
    24                         wait(c);
     24                        wait(&c);
    2525                },
    2626                result
  • src/benchmark/schedint/cfa2.c

    r121ac13 r9f4524b  
    1515
    1616void __attribute__((noinline)) call( M & mutex a1, M & mutex a2 ) {
    17         signal(c);
     17        signal(&c);
    1818}
    1919
     
    2222        BENCH(
    2323                for (size_t i = 0; i < n; i++) {
    24                         wait(c);
     24                        wait(&c);
    2525                },
    2626                result
  • src/benchmark/schedint/cfa4.c

    r121ac13 r9f4524b  
    1515
    1616void __attribute__((noinline)) call( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) {
    17         signal(c);
     17        signal(&c);
    1818}
    1919
     
    2222        BENCH(
    2323                for (size_t i = 0; i < n; i++) {
    24                         wait(c);
     24                        wait(&c);
    2525                },
    2626                result
  • src/libcfa/concurrency/invoke.h

    r121ac13 r9f4524b  
    2525#define _INVOKE_H_
    2626
    27         #define unlikely(x)    __builtin_expect(!!(x), 0)
    28         #define thread_local _Thread_local
     27      #define unlikely(x)    __builtin_expect(!!(x), 0)
     28      #define thread_local _Thread_local
    2929
    30         typedef void (*fptr_t)();
    31         typedef int_fast16_t __lock_size_t;
     30      typedef void (*fptr_t)();
    3231
    33         struct spinlock {
    34                 volatile int lock;
    35                 #ifdef __CFA_DEBUG__
    36                         const char * prev_name;
    37                         void* prev_thrd;
    38                 #endif
    39         };
     32      struct spinlock {
     33            volatile int lock;
     34            #ifdef __CFA_DEBUG__
     35                  const char * prev_name;
     36                  void* prev_thrd;
     37            #endif
     38      };
    4039
    41         struct __thread_queue_t {
    42                 struct thread_desc * head;
    43                 struct thread_desc ** tail;
    44         };
     40      struct __thread_queue_t {
     41            struct thread_desc * head;
     42            struct thread_desc ** tail;
     43      };
    4544
    46         struct __condition_stack_t {
    47                 struct __condition_criterion_t * top;
    48         };
     45      struct __condition_stack_t {
     46            struct __condition_criterion_t * top;
     47      };
    4948
    50         #ifdef __CFORALL__
    51         extern "Cforall" {
    52                 void ?{}( struct __thread_queue_t & );
    53                 void append( struct __thread_queue_t &, struct thread_desc * );
    54                 struct thread_desc * pop_head( struct __thread_queue_t & );
    55                 struct thread_desc * remove( struct __thread_queue_t &, struct thread_desc ** );
     49      #ifdef __CFORALL__
     50      extern "Cforall" {
     51            void ?{}( struct __thread_queue_t & );
     52            void append( struct __thread_queue_t *, struct thread_desc * );
     53            struct thread_desc * pop_head( struct __thread_queue_t * );
     54            struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** );
    5655
    57                 void ?{}( struct __condition_stack_t & );
    58                 void push( struct __condition_stack_t &, struct __condition_criterion_t * );
    59                 struct __condition_criterion_t * pop( struct __condition_stack_t & );
     56            void ?{}( struct __condition_stack_t & );
     57            void push( struct __condition_stack_t *, struct __condition_criterion_t * );
     58            struct __condition_criterion_t * pop( struct __condition_stack_t * );
    6059
    61                 void ?{}(spinlock & this);
    62                 void ^?{}(spinlock & this);
    63         }
    64         #endif
     60            void ?{}(spinlock & this);
     61            void ^?{}(spinlock & this);
     62      }
     63      #endif
    6564
    66         struct coStack_t {
    67                 // size of stack
    68                 size_t size;
     65      struct coStack_t {
     66            unsigned int size;                        // size of stack
     67            void *storage;                            // pointer to stack
     68            void *limit;                              // stack grows towards stack limit
     69            void *base;                               // base of stack
     70            void *context;                            // address of cfa_context_t
     71            void *top;                                // address of top of storage
     72            bool userStack;                           // whether or not the user allocated the stack
     73      };
    6974
    70                 // pointer to stack
    71                 void *storage;
     75      enum coroutine_state { Halted, Start, Inactive, Active, Primed };
    7276
    73                 // stack grows towards stack limit
    74                 void *limit;
     77      struct coroutine_desc {
     78            struct coStack_t stack;                   // stack information of the coroutine
     79            const char *name;                         // textual name for coroutine/task, initialized by uC++ generated code
     80            int errno_;                               // copy of global UNIX variable errno
     81            enum coroutine_state state;               // current execution status for coroutine
     82            struct coroutine_desc * starter;          // first coroutine to resume this one
     83            struct coroutine_desc * last;             // last coroutine to resume this one
     84      };
    7585
    76                 // base of stack
    77                 void *base;
     86      struct __waitfor_mask_t {
     87            short * accepted;                         // the index of the accepted function, -1 if none
     88            struct __acceptable_t * clauses;          // list of acceptable functions, null if any
     89            short size;                               // number of acceptable functions
     90      };
    7891
    79                 // address of cfa_context_t
    80                 void *context;
     92      struct monitor_desc {
     93            struct spinlock lock;                     // spinlock to protect internal data
     94            struct thread_desc * owner;               // current owner of the monitor
     95            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
     96            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
     97            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
     98            struct __waitfor_mask_t mask;             // mask used to know if some thread is waiting for something while holding the monitor
     99            struct __condition_node_t * dtor_node;    // node used to signal the dtor in a waitfor dtor
     100      };
    81101
    82                 // address of top of storage
    83                 void *top;
     102      struct __monitor_group_t {
     103            struct monitor_desc ** list;              // currently held monitors
     104            short                  size;              // number of currently held monitors
     105            fptr_t                 func;              // last function that acquired monitors
     106      };
    84107
    85                 // whether or not the user allocated the stack
    86                 bool userStack;
    87         };
     108      struct thread_desc {
     109            // Core threading fields
     110            struct coroutine_desc  self_cor;          // coroutine body used to store context
     111            struct monitor_desc    self_mon;          // monitor body used for mutual exclusion
     112            struct monitor_desc *  self_mon_p;        // pointer to monitor with sufficient lifetime for current monitors
     113            struct __monitor_group_t monitors;        // monitors currently held by this thread
    88114
    89         enum coroutine_state { Halted, Start, Inactive, Active, Primed };
     115            // Link lists fields
     116            struct thread_desc * next;                // instrusive link field for threads
    90117
    91         struct coroutine_desc {
    92                 // stack information of the coroutine
    93                 struct coStack_t stack;
    94118
    95                 // textual name for coroutine/task, initialized by uC++ generated code
    96                 const char *name;
    97 
    98                 // copy of global UNIX variable errno
    99                 int errno_;
    100 
    101                 // current execution status for coroutine
    102                 enum coroutine_state state;
    103 
    104                 // first coroutine to resume this one
    105                 struct coroutine_desc * starter;
    106 
    107                 // last coroutine to resume this one
    108                 struct coroutine_desc * last;
    109         };
    110 
    111         struct __waitfor_mask_t {
    112                 // the index of the accepted function, -1 if none
    113                 short * accepted;
    114 
    115                 // list of acceptable functions, null if any
    116                 struct __acceptable_t * clauses;
    117 
    118                 // number of acceptable functions
    119                 __lock_size_t size;
    120         };
    121 
    122         struct monitor_desc {
    123                 // spinlock to protect internal data
    124                 struct spinlock lock;
    125 
    126                 // current owner of the monitor
    127                 struct thread_desc * owner;
    128 
    129                 // queue of threads that are blocked waiting for the monitor
    130                 struct __thread_queue_t entry_queue;
    131 
    132                 // stack of conditions to run next once we exit the monitor
    133                 struct __condition_stack_t signal_stack;
    134 
    135                 // monitor routines can be called recursively, we need to keep track of that
    136                 unsigned int recursion;
    137 
    138                 // mask used to know if some thread is waiting for something while holding the monitor
    139                 struct __waitfor_mask_t mask;
    140 
    141                 // node used to signal the dtor in a waitfor dtor
    142                 struct __condition_node_t * dtor_node;
    143         };
    144 
    145         struct __monitor_group_t {
    146                 // currently held monitors
    147                 struct monitor_desc ** list;
    148 
    149                 // number of currently held monitors
    150                 __lock_size_t size;
    151 
    152                 // last function that acquired monitors
    153                 fptr_t func;
    154         };
    155 
    156         struct thread_desc {
    157                 // Core threading fields
    158                 // coroutine body used to store context
    159                 struct coroutine_desc  self_cor;
    160 
    161                 // monitor body used for mutual exclusion
    162                 struct monitor_desc    self_mon;
    163 
    164                 // pointer to monitor with sufficient lifetime for current monitors
    165                 struct monitor_desc *  self_mon_p;
    166 
    167                 // monitors currently held by this thread
    168                 struct __monitor_group_t monitors;
    169 
    170                 // Link lists fields
    171                 // instrusive link field for threads
    172                 struct thread_desc * next;
    173119     };
    174120
    175121     #ifdef __CFORALL__
    176122     extern "Cforall" {
    177                 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    178                         return this.list[index];
    179                 }
     123            static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
     124                  return this.list[index];
     125            }
    180126
    181                 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
    182                         if( (lhs.list != 0) != (rhs.list != 0) ) return false;
    183                         if( lhs.size != rhs.size ) return false;
    184                         if( lhs.func != rhs.func ) return false;
     127            static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
     128                  if( (lhs.list != 0) != (rhs.list != 0) ) return false;
     129                  if( lhs.size != rhs.size ) return false;
     130                  if( lhs.func != rhs.func ) return false;
    185131
    186                         // Check that all the monitors match
    187                         for( int i = 0; i < lhs.size; i++ ) {
    188                                 // If not a match, check next function
    189                                 if( lhs[i] != rhs[i] ) return false;
    190                         }
     132                  // Check that all the monitors match
     133                  for( int i = 0; i < lhs.size; i++ ) {
     134                        // If not a match, check next function
     135                        if( lhs[i] != rhs[i] ) return false;
     136                  }
    191137
    192                         return true;
    193                 }
    194         }
    195         #endif
     138                  return true;
     139            }
     140      }
     141      #endif
    196142
    197143#endif //_INVOKE_H_
     
    200146#define _INVOKE_PRIVATE_H_
    201147
    202         struct machine_context_t {
    203                 void *SP;
    204                 void *FP;
    205                 void *PC;
    206         };
     148      struct machine_context_t {
     149            void *SP;
     150            void *FP;
     151            void *PC;
     152      };
    207153
    208         // assembler routines that performs the context switch
    209         extern void CtxInvokeStub( void );
    210         void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     154      // assembler routines that performs the context switch
     155      extern void CtxInvokeStub( void );
     156      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
    211157
    212         #if   defined( __x86_64__ )
    213         #define CtxGet( ctx ) __asm__ ( \
    214                         "movq %%rsp,%0\n"   \
    215                         "movq %%rbp,%1\n"   \
    216                 : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    217         #elif defined( __i386__ )
    218         #define CtxGet( ctx ) __asm__ ( \
    219                         "movl %%esp,%0\n"   \
    220                         "movl %%ebp,%1\n"   \
    221                 : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    222         #endif
     158      #if   defined( __x86_64__ )
     159      #define CtxGet( ctx ) __asm__ ( \
     160                  "movq %%rsp,%0\n"   \
     161                  "movq %%rbp,%1\n"   \
     162            : "=rm" (ctx.SP), "=rm" (ctx.FP) )
     163      #elif defined( __i386__ )
     164      #define CtxGet( ctx ) __asm__ ( \
     165                  "movl %%esp,%0\n"   \
     166                  "movl %%ebp,%1\n"   \
     167            : "=rm" (ctx.SP), "=rm" (ctx.FP) )
     168      #endif
    223169
    224170#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    r121ac13 r9f4524b  
    2626//-----------------------------------------------------------------------------
    2727// Locks
    28 // Lock the spinlock, spin if already acquired
    29 void lock      ( spinlock * DEBUG_CTX_PARAM2 );
    30 
    31 // Lock the spinlock, yield repeatedly if already acquired
    32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
    33 
    34 // Lock the spinlock, return false if already acquired
    35 bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
    36 
    37 // Unlock the spinlock
    38 void unlock    ( spinlock * );
     28void lock      ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, spin if already acquired
     29void lock_yield( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, yield repeatedly if already acquired
     30bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, return false if already acquired
     31void unlock    ( spinlock * );                        // Unlock the spinlock
    3932
    4033struct semaphore {
     
    4639void  ?{}(semaphore & this, int count = 1);
    4740void ^?{}(semaphore & this);
    48 void   P (semaphore & this);
    49 void   V (semaphore & this);
     41void P(semaphore * this);
     42void V(semaphore * this);
    5043
    5144
     
    5346// Cluster
    5447struct cluster {
    55         // Ready queue locks
    56         spinlock ready_queue_lock;
    57 
    58         // Ready queue for threads
    59         __thread_queue_t ready_queue;
    60 
    61         // Preemption rate on this cluster
    62         unsigned long long int preemption;
     48        spinlock ready_queue_lock;                      // Ready queue locks
     49        __thread_queue_t ready_queue;                   // Ready queue for threads
     50        unsigned long long int preemption;              // Preemption rate on this cluster
    6351};
    6452
    65 void ?{} (cluster & this);
     53void ?{}(cluster & this);
    6654void ^?{}(cluster & this);
    6755
     
    9179struct processor {
    9280        // Main state
    93         // Coroutine ctx who does keeps the state of the processor
    94         struct processorCtx_t * runner;
    95 
    96         // Cluster from which to get threads
    97         cluster * cltr;
    98 
    99         // Handle to pthreads
    100         pthread_t kernel_thread;
     81        struct processorCtx_t * runner;                 // Coroutine ctx who does keeps the state of the processor
     82        cluster * cltr;                                 // Cluster from which to get threads
     83        pthread_t kernel_thread;                        // Handle to pthreads
    10184
    10285        // Termination
    103         // Set to true to notify the processor should terminate
    104         volatile bool do_terminate;
    105 
    106         // Termination synchronisation
    107         semaphore terminated;
     86        volatile bool do_terminate;                     // Set to true to notify the processor should terminate
     87        semaphore terminated;                           // Termination synchronisation
    10888
    10989        // RunThread data
    110         // Action to do after a thread is ran
    111         struct FinishAction finish;
     90        struct FinishAction finish;                     // Action to do after a thread is ran
    11291
    11392        // Preemption data
    114         // Node which is added in the discrete event simulaiton
    115         struct alarm_node_t * preemption_alarm;
    116 
    117         // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
    118         bool pending_preemption;
     93        struct alarm_node_t * preemption_alarm;         // Node which is added in the discrete event simulaiton
     94        bool pending_preemption;                        // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
    11995
    12096#ifdef __CFA_DEBUG__
    121         // Last function to enable preemption on this processor
    122         char * last_enable;
     97        char * last_enable;                             // Last function to enable preemption on this processor
    12398#endif
    12499};
    125100
    126 void  ?{}(processor & this);
    127 void  ?{}(processor & this, cluster * cltr);
     101void ?{}(processor & this);
     102void ?{}(processor & this, cluster * cltr);
    128103void ^?{}(processor & this);
    129104
  • src/libcfa/concurrency/kernel.c

    r121ac13 r9f4524b  
    158158                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this);
    159159                this.do_terminate = true;
    160                 P( this.terminated );
     160                P( &this.terminated );
    161161                pthread_join( this.kernel_thread, NULL );
    162162        }
     
    216216        }
    217217
    218         V( this->terminated );
     218        V( &this->terminated );
    219219
    220220        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
     
    335335
    336336        lock(   &this_processor->cltr->ready_queue_lock DEBUG_CTX2 );
    337         append( this_processor->cltr->ready_queue, thrd );
     337        append( &this_processor->cltr->ready_queue, thrd );
    338338        unlock( &this_processor->cltr->ready_queue_lock );
    339339
     
    344344        verify( disable_preempt_count > 0 );
    345345        lock( &this->ready_queue_lock DEBUG_CTX2 );
    346         thread_desc * head = pop_head( this->ready_queue );
     346        thread_desc * head = pop_head( &this->ready_queue );
    347347        unlock( &this->ready_queue_lock );
    348348        verify( disable_preempt_count > 0 );
     
    398398}
    399399
    400 void BlockInternal(spinlock * locks [], unsigned short count) {
     400void BlockInternal(spinlock ** locks, unsigned short count) {
    401401        disable_interrupts();
    402402        this_processor->finish.action_code = Release_Multi;
     
    411411}
    412412
    413 void BlockInternal(spinlock * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
     413void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    414414        disable_interrupts();
    415415        this_processor->finish.action_code = Release_Multi_Schedule;
     
    618618void ^?{}(semaphore & this) {}
    619619
    620 void P(semaphore & this) {
    621         lock( &this.lock DEBUG_CTX2 );
    622         this.count -= 1;
    623         if ( this.count < 0 ) {
     620void P(semaphore * this) {
     621        lock( &this->lock DEBUG_CTX2 );
     622        this->count -= 1;
     623        if ( this->count < 0 ) {
    624624                // queue current task
    625                 append( this.waiting, (thread_desc *)this_thread );
     625                append( &this->waiting, (thread_desc *)this_thread );
    626626
    627627                // atomically release spin lock and block
    628                 BlockInternal( &this.lock );
     628                BlockInternal( &this->lock );
    629629        }
    630630        else {
    631             unlock( &this.lock );
    632         }
    633 }
    634 
    635 void V(semaphore & this) {
     631            unlock( &this->lock );
     632        }
     633}
     634
     635void V(semaphore * this) {
    636636        thread_desc * thrd = NULL;
    637         lock( &this.lock DEBUG_CTX2 );
    638         this.count += 1;
    639         if ( this.count <= 0 ) {
     637        lock( &this->lock DEBUG_CTX2 );
     638        this->count += 1;
     639        if ( this->count <= 0 ) {
    640640                // remove task at head of waiting list
    641                 thrd = pop_head( this.waiting );
    642         }
    643 
    644         unlock( &this.lock );
     641                thrd = pop_head( &this->waiting );
     642        }
     643
     644        unlock( &this->lock );
    645645
    646646        // make new owner
     
    655655}
    656656
    657 void append( __thread_queue_t & this, thread_desc * t ) {
    658         verify(this.tail != NULL);
    659         *this.tail = t;
    660         this.tail = &t->next;
    661 }
    662 
    663 thread_desc * pop_head( __thread_queue_t & this ) {
    664         thread_desc * head = this.head;
     657void append( __thread_queue_t * this, thread_desc * t ) {
     658        verify(this->tail != NULL);
     659        *this->tail = t;
     660        this->tail = &t->next;
     661}
     662
     663thread_desc * pop_head( __thread_queue_t * this ) {
     664        thread_desc * head = this->head;
    665665        if( head ) {
    666                 this.head = head->next;
     666                this->head = head->next;
    667667                if( !head->next ) {
    668                         this.tail = &this.head;
     668                        this->tail = &this->head;
    669669                }
    670670                head->next = NULL;
     
    673673}
    674674
    675 thread_desc * remove( __thread_queue_t & this, thread_desc ** it ) {
     675thread_desc * remove( __thread_queue_t * this, thread_desc ** it ) {
    676676        thread_desc * thrd = *it;
    677677        verify( thrd );
     
    679679        (*it) = thrd->next;
    680680
    681         if( this.tail == &thrd->next ) {
    682                 this.tail = it;
     681        if( this->tail == &thrd->next ) {
     682                this->tail = it;
    683683        }
    684684
    685685        thrd->next = NULL;
    686686
    687         verify( (this.head == NULL) == (&this.head == this.tail) );
    688         verify( *this.tail == NULL );
     687        verify( (this->head == NULL) == (&this->head == this->tail) );
     688        verify( *this->tail == NULL );
    689689        return thrd;
    690690}
     
    694694}
    695695
    696 void push( __condition_stack_t & this, __condition_criterion_t * t ) {
     696void push( __condition_stack_t * this, __condition_criterion_t * t ) {
    697697        verify( !t->next );
    698         t->next = this.top;
    699         this.top = t;
    700 }
    701 
    702 __condition_criterion_t * pop( __condition_stack_t & this ) {
    703         __condition_criterion_t * top = this.top;
     698        t->next = this->top;
     699        this->top = t;
     700}
     701
     702__condition_criterion_t * pop( __condition_stack_t * this ) {
     703        __condition_criterion_t * top = this->top;
    704704        if( top ) {
    705                 this.top = top->next;
     705                this->top = top->next;
    706706                top->next = NULL;
    707707        }
  • src/libcfa/concurrency/kernel_private.h

    r121ac13 r9f4524b  
    4848void BlockInternal(thread_desc * thrd);
    4949void BlockInternal(spinlock * lock, thread_desc * thrd);
    50 void BlockInternal(spinlock * locks [], unsigned short count);
    51 void BlockInternal(spinlock * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);
     50void BlockInternal(spinlock ** locks, unsigned short count);
     51void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
    5252void LeaveThread(spinlock * lock, thread_desc * thrd);
    5353
  • src/libcfa/concurrency/monitor

    r121ac13 r9f4524b  
    3939}
    4040
     41// static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
     42//      return ((intptr_t)lhs) < ((intptr_t)rhs);
     43// }
     44
    4145struct monitor_guard_t {
    4246        monitor_desc ** m;
    43         __lock_size_t  count;
     47        int count;
    4448        monitor_desc ** prev_mntrs;
    45         __lock_size_t   prev_count;
     49        unsigned short  prev_count;
    4650        fptr_t          prev_func;
    4751};
    4852
    49 void ?{}( monitor_guard_t & this, monitor_desc ** m, __lock_size_t count, void (*func)() );
     53void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
    5054void ^?{}( monitor_guard_t & this );
    5155
     
    5357        monitor_desc * m;
    5458        monitor_desc ** prev_mntrs;
    55         __lock_size_t   prev_count;
     59        unsigned short  prev_count;
    5660        fptr_t          prev_func;
    5761};
     
    7074
    7175struct __condition_criterion_t {
    72         // Whether or not the criterion is met (True if met)
    73         bool ready;
    74 
    75         // The monitor this criterion concerns
    76         monitor_desc * target;
    77 
    78         // The parent node to which this criterion belongs
    79         struct __condition_node_t * owner;
    80 
    81         // Intrusive linked list Next field
    82         __condition_criterion_t * next;
     76        bool ready;                                             //Whether or not the criterion is met (True if met)
     77        monitor_desc * target;                          //The monitor this criterion concerns
     78        struct __condition_node_t * owner;              //The parent node to which this criterion belongs
     79        __condition_criterion_t * next;         //Intrusive linked list Next field
    8380};
    8481
    8582struct __condition_node_t {
    86         // Thread that needs to be woken when all criteria are met
    87         thread_desc * waiting_thread;
    88 
    89         // Array of criteria (Criterions are contiguous in memory)
    90         __condition_criterion_t * criteria;
    91 
    92         // Number of criterions in the criteria
    93         __lock_size_t count;
    94 
    95         // Intrusive linked list Next field
    96         __condition_node_t * next;
    97 
    98         // Custom user info accessible before signalling
    99         uintptr_t user_info;
     83        thread_desc * waiting_thread;                   //Thread that needs to be woken when all criteria are met
     84        __condition_criterion_t * criteria;     //Array of criteria (Criterions are contiguous in memory)
     85        unsigned short count;                           //Number of criterions in the criteria
     86        __condition_node_t * next;                      //Intrusive linked list Next field
     87        uintptr_t user_info;                            //Custom user info accessible before signalling
    10088};
    10189
     
    10593};
    10694
    107 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info );
     95void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info );
    10896void ?{}(__condition_criterion_t & this );
    10997void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner );
    11098
    11199void ?{}( __condition_blocked_queue_t & );
    112 void append( __condition_blocked_queue_t &, __condition_node_t * );
    113 __condition_node_t * pop_head( __condition_blocked_queue_t & );
     100void append( __condition_blocked_queue_t *, __condition_node_t * );
     101__condition_node_t * pop_head( __condition_blocked_queue_t * );
    114102
    115103struct condition {
    116         // Link list which contains the blocked threads as-well as the information needed to unblock them
    117         __condition_blocked_queue_t blocked;
    118 
    119         // Array of monitor pointers (Monitors are NOT contiguous in memory)
    120         monitor_desc ** monitors;
    121 
    122         // Number of monitors in the array
    123         __lock_size_t monitor_count;
     104        __condition_blocked_queue_t blocked;    //Link list which contains the blocked threads as-well as the information needed to unblock them
     105        monitor_desc ** monitors;                       //Array of monitor pointers (Monitors are NOT contiguous in memory)
     106        unsigned short monitor_count;                   //Number of monitors in the array
    124107};
    125108
     
    133116}
    134117
    135               void wait        ( condition & this, uintptr_t user_info = 0 );
    136               bool signal      ( condition & this );
    137               bool signal_block( condition & this );
    138 static inline bool is_empty    ( condition & this ) { return !this.blocked.head; }
    139          uintptr_t front       ( condition & this );
     118void wait( condition * this, uintptr_t user_info = 0 );
     119bool signal( condition * this );
     120bool signal_block( condition * this );
     121static inline bool is_empty( condition * this ) { return !this->blocked.head; }
     122uintptr_t front( condition * this );
    140123
    141124//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor.c

    r121ac13 r9f4524b  
    2626// Forward declarations
    2727static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    28 static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );
    29 static inline void set_mask  ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask );
     28static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner );
     29static inline void set_mask  ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
    3030static inline void reset_mask( monitor_desc * this );
    3131
     
    3333static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
    3434
    35 static inline void lock_all  ( spinlock * locks [], __lock_size_t count );
    36 static inline void lock_all  ( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count );
    37 static inline void unlock_all( spinlock * locks [], __lock_size_t count );
    38 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );
    39 
    40 static inline void save   ( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
    41 static inline void restore( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
    42 
    43 static inline void init     ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
    44 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     35static inline void lock_all( spinlock ** locks, unsigned short count );
     36static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
     37static inline void unlock_all( spinlock ** locks, unsigned short count );
     38static inline void unlock_all( monitor_desc ** locks, unsigned short count );
     39
     40static inline void save   ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks );
     41static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks );
     42
     43static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     44static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    4545
    4646static inline thread_desc *        check_condition   ( __condition_criterion_t * );
    47 static inline void                 brand_condition   ( condition & );
    48 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );
     47static inline void                 brand_condition   ( condition * );
     48static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count );
    4949
    5050forall(dtype T | sized( T ))
    51 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );
    52 static inline __lock_size_t count_max    ( const __waitfor_mask_t & mask );
    53 static inline __lock_size_t aggregate    ( monitor_desc * storage [], const __waitfor_mask_t & mask );
     51static inline short insert_unique( T ** array, short & size, T * val );
     52static inline short count_max    ( const __waitfor_mask_t & mask );
     53static inline short aggregate    ( monitor_desc ** storage, const __waitfor_mask_t & mask );
    5454
    5555//-----------------------------------------------------------------------------
     
    5858        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    5959        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    60         init( count, monitors, waiter, criteria );                /* Link everything together                                                            */ \
     60        init( count, monitors, &waiter, criteria );               /* Link everything together                                                            */ \
    6161
    6262#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack                         */ \
    6363        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    6464        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    65         init_push( count, monitors, waiter, criteria );           /* Link everything together and push it to the AS-Stack                                */ \
     65        init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack                                */ \
    6666
    6767#define monitor_ctx( mons, cnt )                                /* Define that create the necessary struct for internal/external scheduling operations */ \
    6868        monitor_desc ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
    69         __lock_size_t count = cnt;                                /* Save the count to a local variable                                                  */ \
     69        unsigned short count = cnt;                               /* Save the count to a local variable                                                  */ \
    7070        unsigned int recursions[ count ];                         /* Save the current recursion levels to restore them later                             */ \
    71         __waitfor_mask_t masks [ count ];                         /* Save the current waitfor masks to restore them later                                */ \
     71        __waitfor_mask_t masks[ count ];                          /* Save the current waitfor masks to restore them later                                */ \
    7272        spinlock *   locks     [ count ];                         /* We need to pass-in an array of locks to BlockInternal                               */ \
    7373
     
    114114
    115115                        // Some one else has the monitor, wait in line for it
    116                         append( this->entry_queue, thrd );
     116                        append( &this->entry_queue, thrd );
    117117                        BlockInternal( &this->lock );
    118118
     
    153153                }
    154154
    155                 __lock_size_t count = 1;
     155                int count = 1;
    156156                monitor_desc ** monitors = &this;
    157157                __monitor_group_t group = { &this, 1, func };
     
    160160
    161161                        // Wake the thread that is waiting for this
    162                         __condition_criterion_t * urgent = pop( this->signal_stack );
     162                        __condition_criterion_t * urgent = pop( &this->signal_stack );
    163163                        verify( urgent );
    164164
     
    182182
    183183                        // Some one else has the monitor, wait in line for it
    184                         append( this->entry_queue, thrd );
     184                        append( &this->entry_queue, thrd );
    185185                        BlockInternal( &this->lock );
    186186
     
    272272// relies on the monitor array being sorted
    273273static inline void enter( __monitor_group_t monitors ) {
    274         for( __lock_size_t i = 0; i < monitors.size; i++) {
     274        for(int i = 0; i < monitors.size; i++) {
    275275                __enter_monitor_desc( monitors.list[i], monitors );
    276276        }
     
    279279// Leave multiple monitor
    280280// relies on the monitor array being sorted
    281 static inline void leave(monitor_desc * monitors [], __lock_size_t count) {
    282         for( __lock_size_t i = count - 1; i >= 0; i--) {
     281static inline void leave(monitor_desc ** monitors, int count) {
     282        for(int i = count - 1; i >= 0; i--) {
    283283                __leave_monitor_desc( monitors[i] );
    284284        }
     
    287287// Ctor for monitor guard
    288288// Sorts monitors before entering
    289 void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
     289void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
    290290        // Store current array
    291291        this.m = m;
     
    296296
    297297        // Save previous thread context
    298         this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     298        this.prev_mntrs = this_thread->monitors.list;
     299        this.prev_count = this_thread->monitors.size;
     300        this.prev_func  = this_thread->monitors.func;
    299301
    300302        // Update thread context (needed for conditions)
    301         this_thread->monitors.[list, size, func] = [m, count, func];
     303        this_thread->monitors.list = m;
     304        this_thread->monitors.size = count;
     305        this_thread->monitors.func = func;
    302306
    303307        // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     
    321325
    322326        // Restore thread context
    323         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
    324 }
     327        this_thread->monitors.list = this.prev_mntrs;
     328        this_thread->monitors.size = this.prev_count;
     329        this_thread->monitors.func = this.prev_func;
     330}
     331
    325332
    326333// Ctor for monitor guard
    327334// Sorts monitors before entering
    328 void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
     335void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
    329336        // Store current array
    330337        this.m = *m;
    331338
    332339        // Save previous thread context
    333         this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     340        this.prev_mntrs = this_thread->monitors.list;
     341        this.prev_count = this_thread->monitors.size;
     342        this.prev_func  = this_thread->monitors.func;
    334343
    335344        // Update thread context (needed for conditions)
    336         this_thread->monitors.[list, size, func] = [m, 1, func];
     345        this_thread->monitors.list = m;
     346        this_thread->monitors.size = 1;
     347        this_thread->monitors.func = func;
    337348
    338349        __enter_monitor_dtor( this.m, func );
    339350}
     351
    340352
    341353// Dtor for monitor guard
     
    345357
    346358        // Restore thread context
    347         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     359        this_thread->monitors.list = this.prev_mntrs;
     360        this_thread->monitors.size = this.prev_count;
     361        this_thread->monitors.func = this.prev_func;
    348362}
    349363
    350364//-----------------------------------------------------------------------------
    351365// Internal scheduling types
    352 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
     366void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
    353367        this.waiting_thread = waiting_thread;
    354368        this.count = count;
     
    364378}
    365379
    366 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) {
     380void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ) {
    367381        this.ready  = false;
    368382        this.target = target;
    369         this.owner  = &owner;
     383        this.owner  = owner;
    370384        this.next   = NULL;
    371385}
     
    373387//-----------------------------------------------------------------------------
    374388// Internal scheduling
    375 void wait( condition & this, uintptr_t user_info = 0 ) {
     389void wait( condition * this, uintptr_t user_info = 0 ) {
    376390        brand_condition( this );
    377391
    378392        // Check that everything is as expected
    379         assertf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
    380         verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%i)", this.monitor_count );
    381         verifyf( this.monitor_count < 32u, "Excessive monitor count (%i)", this.monitor_count );
     393        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
     394        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     395        verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
    382396
    383397        // Create storage for monitor context
    384         monitor_ctx( this.monitors, this.monitor_count );
     398        monitor_ctx( this->monitors, this->monitor_count );
    385399
    386400        // Create the node specific to this wait operation
     
    389403        // Append the current wait operation to the ones already queued on the condition
    390404        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
    391         append( this.blocked, &waiter );
     405        append( &this->blocked, &waiter );
    392406
    393407        // Lock all monitors (aggregates the locks as well)
     
    395409
    396410        // Find the next thread(s) to run
    397         __lock_size_t thread_count = 0;
     411        short thread_count = 0;
    398412        thread_desc * threads[ count ];
    399413        __builtin_memset( threads, 0, sizeof( threads ) );
     
    403417
    404418        // Remove any duplicate threads
    405         for( __lock_size_t i = 0; i < count; i++) {
     419        for( int i = 0; i < count; i++) {
    406420                thread_desc * new_owner = next_thread( monitors[i] );
    407421                insert_unique( threads, thread_count, new_owner );
     
    415429}
    416430
    417 bool signal( condition & this ) {
     431bool signal( condition * this ) {
    418432        if( is_empty( this ) ) { return false; }
    419433
    420434        //Check that everything is as expected
    421         verify( this.monitors );
    422         verify( this.monitor_count != 0 );
     435        verify( this->monitors );
     436        verify( this->monitor_count != 0 );
    423437
    424438        //Some more checking in debug
    425439        LIB_DEBUG_DO(
    426440                thread_desc * this_thrd = this_thread;
    427                 if ( this.monitor_count != this_thrd->monitors.size ) {
    428                         abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size );
    429                 }
    430 
    431                 for(int i = 0; i < this.monitor_count; i++) {
    432                         if ( this.monitors[i] != this_thrd->monitors.list[i] ) {
    433                                 abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors.list[i] );
     441                if ( this->monitor_count != this_thrd->monitors.size ) {
     442                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );
     443                }
     444
     445                for(int i = 0; i < this->monitor_count; i++) {
     446                        if ( this->monitors[i] != this_thrd->monitors.list[i] ) {
     447                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );
    434448                        }
    435449                }
    436450        );
    437451
    438         __lock_size_t count = this.monitor_count;
     452        unsigned short count = this->monitor_count;
    439453
    440454        // Lock all monitors
    441         lock_all( this.monitors, NULL, count );
     455        lock_all( this->monitors, NULL, count );
    442456
    443457        //Pop the head of the waiting queue
    444         __condition_node_t * node = pop_head( this.blocked );
     458        __condition_node_t * node = pop_head( &this->blocked );
    445459
    446460        //Add the thread to the proper AS stack
     
    448462                __condition_criterion_t * crit = &node->criteria[i];
    449463                assert( !crit->ready );
    450                 push( crit->target->signal_stack, crit );
     464                push( &crit->target->signal_stack, crit );
    451465        }
    452466
    453467        //Release
    454         unlock_all( this.monitors, count );
     468        unlock_all( this->monitors, count );
    455469
    456470        return true;
    457471}
    458472
    459 bool signal_block( condition & this ) {
    460         if( !this.blocked.head ) { return false; }
     473bool signal_block( condition * this ) {
     474        if( !this->blocked.head ) { return false; }
    461475
    462476        //Check that everything is as expected
    463         verifyf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
    464         verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%i)", this.monitor_count );
     477        verifyf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
     478        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    465479
    466480        // Create storage for monitor context
    467         monitor_ctx( this.monitors, this.monitor_count );
     481        monitor_ctx( this->monitors, this->monitor_count );
    468482
    469483        // Lock all monitors (aggregates the locks them as well)
     
    477491
    478492        //Find the thread to run
    479         thread_desc * signallee = pop_head( this.blocked )->waiting_thread;
     493        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
    480494        set_owner( monitors, count, signallee );
    481495
    482         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
     496        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );
    483497
    484498        //Everything is ready to go to sleep
     
    498512
    499513// Access the user_info of the thread waiting at the front of the queue
    500 uintptr_t front( condition & this ) {
     514uintptr_t front( condition * this ) {
    501515        verifyf( !is_empty(this),
    502516                "Attempt to access user data on an empty condition.\n"
    503517                "Possible cause is not checking if the condition is empty before reading stored data."
    504518        );
    505         return this.blocked.head->user_info;
     519        return this->blocked.head->user_info;
    506520}
    507521
     
    523537        // This statment doesn't have a contiguous list of monitors...
    524538        // Create one!
    525         __lock_size_t max = count_max( mask );
     539        short max = count_max( mask );
    526540        monitor_desc * mon_storage[max];
    527541        __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    528         __lock_size_t actual_count = aggregate( mon_storage, mask );
    529 
    530         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
     542        short actual_count = aggregate( mon_storage, mask );
     543
     544        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max);
    531545
    532546        if(actual_count == 0) return;
     
    555569
    556570                                __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    557                                 push( mon2dtor->signal_stack, dtor_crit );
     571                                push( &mon2dtor->signal_stack, dtor_crit );
    558572
    559573                                unlock_all( locks, count );
     
    615629        set_mask( monitors, count, mask );
    616630
    617         for( __lock_size_t i = 0; i < count; i++) {
     631        for(int i = 0; i < count; i++) {
    618632                verify( monitors[i]->owner == this_thread );
    619633        }
     
    647661}
    648662
    649 static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {
     663static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {
    650664        monitors[0]->owner     = owner;
    651665        monitors[0]->recursion = 1;
    652         for( __lock_size_t i = 1; i < count; i++ ) {
     666        for( int i = 1; i < count; i++ ) {
    653667                monitors[i]->owner     = owner;
    654668                monitors[i]->recursion = 0;
     
    656670}
    657671
    658 static inline void set_mask( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) {
    659         for( __lock_size_t i = 0; i < count; i++) {
     672static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
     673        for(int i = 0; i < count; i++) {
    660674                storage[i]->mask = mask;
    661675        }
     
    671685        //Check the signaller stack
    672686        LIB_DEBUG_PRINT_SAFE("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
    673         __condition_criterion_t * urgent = pop( this->signal_stack );
     687        __condition_criterion_t * urgent = pop( &this->signal_stack );
    674688        if( urgent ) {
    675689                //The signaller stack is not empty,
     
    683697        // No signaller thread
    684698        // Get the next thread in the entry_queue
    685         thread_desc * new_owner = pop_head( this->entry_queue );
     699        thread_desc * new_owner = pop_head( &this->entry_queue );
    686700        set_owner( this, new_owner );
    687701
     
    691705static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    692706        __acceptable_t * it = this->mask.clauses; // Optim
    693         __lock_size_t count = this->mask.size;
     707        int count = this->mask.size;
    694708
    695709        // Check if there are any acceptable functions
     
    700714
    701715        // For all acceptable functions check if this is the current function.
    702         for( __lock_size_t i = 0; i < count; i++, it++ ) {
     716        for( short i = 0; i < count; i++, it++ ) {
    703717                if( *it == group ) {
    704718                        *this->mask.accepted = i;
     
    711725}
    712726
    713 static inline void init( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
    714         for( __lock_size_t i = 0; i < count; i++) {
     727static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
     728        for(int i = 0; i < count; i++) {
    715729                (criteria[i]){ monitors[i], waiter };
    716730        }
    717731
    718         waiter.criteria = criteria;
    719 }
    720 
    721 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
    722         for( __lock_size_t i = 0; i < count; i++) {
     732        waiter->criteria = criteria;
     733}
     734
     735static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
     736        for(int i = 0; i < count; i++) {
    723737                (criteria[i]){ monitors[i], waiter };
    724738                LIB_DEBUG_PRINT_SAFE( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
    725                 push( criteria[i].target->signal_stack, &criteria[i] );
    726         }
    727 
    728         waiter.criteria = criteria;
    729 }
    730 
    731 static inline void lock_all( spinlock * locks [], __lock_size_t count ) {
    732         for( __lock_size_t i = 0; i < count; i++ ) {
     739                push( &criteria[i].target->signal_stack, &criteria[i] );
     740        }
     741
     742        waiter->criteria = criteria;
     743}
     744
     745static inline void lock_all( spinlock ** locks, unsigned short count ) {
     746        for( int i = 0; i < count; i++ ) {
    733747                lock_yield( locks[i] DEBUG_CTX2 );
    734748        }
    735749}
    736750
    737 static inline void lock_all( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count ) {
    738         for( __lock_size_t i = 0; i < count; i++ ) {
     751static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) {
     752        for( int i = 0; i < count; i++ ) {
    739753                spinlock * l = &source[i]->lock;
    740754                lock_yield( l DEBUG_CTX2 );
     
    743757}
    744758
    745 static inline void unlock_all( spinlock * locks [], __lock_size_t count ) {
    746         for( __lock_size_t i = 0; i < count; i++ ) {
     759static inline void unlock_all( spinlock ** locks, unsigned short count ) {
     760        for( int i = 0; i < count; i++ ) {
    747761                unlock( locks[i] );
    748762        }
    749763}
    750764
    751 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) {
    752         for( __lock_size_t i = 0; i < count; i++ ) {
     765static inline void unlock_all( monitor_desc ** locks, unsigned short count ) {
     766        for( int i = 0; i < count; i++ ) {
    753767                unlock( &locks[i]->lock );
    754768        }
    755769}
    756770
    757 static inline void save(
    758         monitor_desc * ctx [],
    759         __lock_size_t count,
    760         __attribute((unused)) spinlock * locks [],
    761         unsigned int /*out*/ recursions [],
    762         __waitfor_mask_t /*out*/ masks []
    763 ) {
    764         for( __lock_size_t i = 0; i < count; i++ ) {
     771static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
     772        for( int i = 0; i < count; i++ ) {
    765773                recursions[i] = ctx[i]->recursion;
    766774                masks[i]      = ctx[i]->mask;
     
    768776}
    769777
    770 static inline void restore(
    771         monitor_desc * ctx [],
    772         __lock_size_t count,
    773         spinlock * locks [],
    774         unsigned int /*out*/ recursions [],
    775         __waitfor_mask_t /*out*/ masks []
    776 ) {
     778static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
    777779        lock_all( locks, count );
    778         for( __lock_size_t i = 0; i < count; i++ ) {
     780        for( int i = 0; i < count; i++ ) {
    779781                ctx[i]->recursion = recursions[i];
    780782                ctx[i]->mask      = masks[i];
     
    809811}
    810812
    811 static inline void brand_condition( condition & this ) {
     813static inline void brand_condition( condition * this ) {
    812814        thread_desc * thrd = this_thread;
    813         if( !this.monitors ) {
     815        if( !this->monitors ) {
    814816                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    815817                assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
    816                 this.monitor_count = thrd->monitors.size;
    817 
    818                 this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) );
    819                 for( int i = 0; i < this.monitor_count; i++ ) {
    820                         this.monitors[i] = thrd->monitors.list[i];
    821                 }
    822         }
    823 }
    824 
    825 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) {
    826 
    827         __thread_queue_t & entry_queue = monitors[0]->entry_queue;
     818                this->monitor_count = thrd->monitors.size;
     819
     820                this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );
     821                for( int i = 0; i < this->monitor_count; i++ ) {
     822                        this->monitors[i] = thrd->monitors.list[i];
     823                }
     824        }
     825}
     826
     827static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) {
     828
     829        __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
    828830
    829831        // For each thread in the entry-queue
    830         for(    thread_desc ** thrd_it = &entry_queue.head;
     832        for(    thread_desc ** thrd_it = &entry_queue->head;
    831833                *thrd_it;
    832834                thrd_it = &(*thrd_it)->next
     
    850852
    851853forall(dtype T | sized( T ))
    852 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) {
     854static inline short insert_unique( T ** array, short & size, T * val ) {
    853855        if( !val ) return size;
    854856
    855         for( __lock_size_t i = 0; i <= size; i++) {
     857        for(int i = 0; i <= size; i++) {
    856858                if( array[i] == val ) return size;
    857859        }
     
    862864}
    863865
    864 static inline __lock_size_t count_max( const __waitfor_mask_t & mask ) {
    865         __lock_size_t max = 0;
    866         for( __lock_size_t i = 0; i < mask.size; i++ ) {
     866static inline short count_max( const __waitfor_mask_t & mask ) {
     867        short max = 0;
     868        for( int i = 0; i < mask.size; i++ ) {
    867869                max += mask.clauses[i].size;
    868870        }
     
    870872}
    871873
    872 static inline __lock_size_t aggregate( monitor_desc * storage [], const __waitfor_mask_t & mask ) {
    873         __lock_size_t size = 0;
    874         for( __lock_size_t i = 0; i < mask.size; i++ ) {
     874static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
     875        short size = 0;
     876        for( int i = 0; i < mask.size; i++ ) {
    875877                __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size );
    876                 for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {
     878                for( int j = 0; j < mask.clauses[i].size; j++) {
    877879                        insert_unique( storage, size, mask.clauses[i].list[j] );
    878880                }
     
    888890}
    889891
    890 void append( __condition_blocked_queue_t & this, __condition_node_t * c ) {
    891         verify(this.tail != NULL);
    892         *this.tail = c;
    893         this.tail = &c->next;
    894 }
    895 
    896 __condition_node_t * pop_head( __condition_blocked_queue_t & this ) {
    897         __condition_node_t * head = this.head;
     892void append( __condition_blocked_queue_t * this, __condition_node_t * c ) {
     893        verify(this->tail != NULL);
     894        *this->tail = c;
     895        this->tail = &c->next;
     896}
     897
     898__condition_node_t * pop_head( __condition_blocked_queue_t * this ) {
     899        __condition_node_t * head = this->head;
    898900        if( head ) {
    899                 this.head = head->next;
     901                this->head = head->next;
    900902                if( !head->next ) {
    901                         this.tail = &this.head;
     903                        this->tail = &this->head;
    902904                }
    903905                head->next = NULL;
  • src/tests/boundedBuffer.c

    r121ac13 r9f4524b  
    1 //
     1// 
    22// The contents of this file are covered under the licence agreement in the
    33// file "LICENCE" distributed with Cforall.
    4 //
    5 // boundedBuffer.c --
    6 //
     4// 
     5// boundedBuffer.c -- 
     6// 
    77// Author           : Peter A. Buhr
    88// Created On       : Mon Oct 30 12:45:13 2017
     
    1010// Last Modified On : Mon Oct 30 23:02:46 2017
    1111// Update Count     : 9
    12 //
     12// 
    1313
    1414#include <stdlib>
     
    3131
    3232void insert( Buffer & mutex buffer, int elem ) {
    33         if ( buffer.count == 20 ) wait( buffer.empty );
     33        if ( buffer.count == 20 ) wait( &buffer.empty );
    3434        buffer.elements[buffer.back] = elem;
    3535        buffer.back = ( buffer.back + 1 ) % 20;
    3636        buffer.count += 1;
    37         signal( buffer.full );
     37        signal( &buffer.full );
    3838}
    3939int remove( Buffer & mutex buffer ) {
    40         if ( buffer.count == 0 ) wait( buffer.full );
     40        if ( buffer.count == 0 ) wait( &buffer.full );
    4141        int elem = buffer.elements[buffer.front];
    4242        buffer.front = ( buffer.front + 1 ) % 20;
    4343        buffer.count -= 1;
    44         signal( buffer.empty );
     44        signal( &buffer.empty );
    4545        return elem;
    4646}
  • src/tests/datingService.c

    r121ac13 r9f4524b  
    1 //                               -*- Mode: C -*-
    2 //
     1//                               -*- Mode: C -*- 
     2// 
    33// The contents of this file are covered under the licence agreement in the
    44// file "LICENCE" distributed with Cforall.
    5 //
    6 // datingService.c --
    7 //
     5// 
     6// datingService.c -- 
     7// 
    88// Author           : Peter A. Buhr
    99// Created On       : Mon Oct 30 12:56:20 2017
     
    1111// Last Modified On : Mon Oct 30 23:02:11 2017
    1212// Update Count     : 15
    13 //
     13// 
    1414
    1515#include <stdlib>                                                                               // random
     
    1818#include <thread>
    1919#include <unistd.h>                                                                             // getpid
     20
     21bool empty( condition & c ) {
     22        return c.blocked.head == NULL;
     23}
    2024
    2125enum { NoOfPairs = 20 };
     
    2731
    2832unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
    29         if ( is_empty( ds.Boys[ccode] ) ) {
    30                 wait( ds.Girls[ccode] );
     33        if ( empty( ds.Boys[ccode] ) ) {
     34                wait( &ds.Girls[ccode] );
    3135                ds.GirlPhoneNo = PhoneNo;
    3236        } else {
    3337                ds.GirlPhoneNo = PhoneNo;
    34                 signal_block( ds.Boys[ccode] );
     38                signal_block( &ds.Boys[ccode] );
    3539        } // if
    3640        return ds.BoyPhoneNo;
     
    3842
    3943unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
    40         if ( is_empty( ds.Girls[ccode] ) ) {
    41                 wait( ds.Boys[ccode] );
     44        if ( empty( ds.Girls[ccode] ) ) {
     45                wait( &ds.Boys[ccode] );
    4246                ds.BoyPhoneNo = PhoneNo;
    4347        } else {
    4448                ds.BoyPhoneNo = PhoneNo;
    45                 signal_block( ds.Girls[ccode] );
     49                signal_block( &ds.Girls[ccode] );
    4650        } // if
    4751        return ds.GirlPhoneNo;
  • src/tests/sched-int-barge.c

    r121ac13 r9f4524b  
    7373        if( action == c.do_wait1 || action == c.do_wait2 ) {
    7474                c.state = WAIT;
    75                 wait( cond );
     75                wait( &cond );
    7676
    7777                if(c.state != SIGNAL) {
     
    8383                c.state = SIGNAL;
    8484
    85                 signal( cond );
    86                 signal( cond );
     85                signal( &cond );
     86                signal( &cond );
    8787        }
    8888        else {
  • src/tests/sched-int-block.c

    r121ac13 r9f4524b  
    4747//------------------------------------------------------------------------------
    4848void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) {
    49         wait( cond, (uintptr_t)this_thread );
     49        wait( &cond, (uintptr_t)this_thread );
    5050
    5151        yield( random( 10 ) );
     
    7474        [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = this_thread;
    7575
    76         if( !is_empty( cond ) ) {
     76        if( !is_empty( &cond ) ) {
    7777
    78                 thread_desc * next = front( cond );
     78                thread_desc * next = front( &cond );
    7979
    80                 if( ! signal_block( cond ) ) {
     80                if( ! signal_block( &cond ) ) {
    8181                        sout | "ERROR expected to be able to signal" | endl;
    8282                        abort();
  • src/tests/sched-int-disjoint.c

    r121ac13 r9f4524b  
    5959// Waiting logic
    6060bool wait( global_t & mutex m, global_data_t & mutex d ) {
    61         wait( cond );
     61        wait( &cond );
    6262        if( d.state != SIGNAL ) {
    6363                sout | "ERROR barging!" | endl;
     
    8080//------------------------------------------------------------------------------
    8181// Signalling logic
    82 void signal( condition & cond, global_t & mutex a, global_data_t & mutex b ) {
     82void signal( condition * cond, global_t & mutex a, global_data_t & mutex b ) {
    8383        b.state = SIGNAL;
    8484        signal( cond );
     
    8686
    8787void logic( global_t & mutex a ) {
    88         signal( cond, a, data );
     88        signal( &cond, a, data );
    8989
    9090        yield( random( 10 ) );
  • src/tests/sched-int-wait.c

    r121ac13 r9f4524b  
    4141//----------------------------------------------------------------------------------------------------
    4242// Tools
    43 void signal( condition & cond, global_t & mutex a, global_t & mutex b ) {
     43void signal( condition * cond, global_t & mutex a, global_t & mutex b ) {
    4444        signal( cond );
    4545}
    4646
    47 void signal( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
     47void signal( condition * cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
    4848        signal( cond );
    4949}
    5050
    51 void wait( condition & cond, global_t & mutex a, global_t & mutex b ) {
     51void wait( condition * cond, global_t & mutex a, global_t & mutex b ) {
    5252        wait( cond );
    5353}
    5454
    55 void wait( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
     55void wait( condition * cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
    5656        wait( cond );
    5757}
     
    6565                switch( action ) {
    6666                        case 0:
    67                                 signal( condABC, globalA, globalB, globalC );
     67                                signal( &condABC, globalA, globalB, globalC );
    6868                                break;
    6969                        case 1:
    70                                 signal( condAB , globalA, globalB );
     70                                signal( &condAB , globalA, globalB );
    7171                                break;
    7272                        case 2:
    73                                 signal( condBC , globalB, globalC );
     73                                signal( &condBC , globalB, globalC );
    7474                                break;
    7575                        case 3:
    76                                 signal( condAC , globalA, globalC );
     76                                signal( &condAC , globalA, globalC );
    7777                                break;
    7878                        default:
     
    8888void main( WaiterABC & this ) {
    8989        for( int i = 0; i < N; i++ ) {
    90                 wait( condABC, globalA, globalB, globalC );
     90                wait( &condABC, globalA, globalB, globalC );
    9191        }
    9292
     
    9898void main( WaiterAB & this ) {
    9999        for( int i = 0; i < N; i++ ) {
    100                 wait( condAB , globalA, globalB );
     100                wait( &condAB , globalA, globalB );
    101101        }
    102102
     
    108108void main( WaiterAC & this ) {
    109109        for( int i = 0; i < N; i++ ) {
    110                 wait( condAC , globalA, globalC );
     110                wait( &condAC , globalA, globalC );
    111111        }
    112112
     
    118118void main( WaiterBC & this ) {
    119119        for( int i = 0; i < N; i++ ) {
    120                 wait( condBC , globalB, globalC );
     120                wait( &condBC , globalB, globalC );
    121121        }
    122122
  • src/tests/thread.c

    r121ac13 r9f4524b  
    1515                yield();
    1616        }
    17         V(*this.lock);
     17        V(this.lock);
    1818}
    1919
    2020void main(Second& this) {
    21         P(*this.lock);
     21        P(this.lock);
    2222        for(int i = 0; i < 10; i++) {
    2323                sout | "Second : Suspend No." | i + 1 | endl;
Note: See TracChangeset for help on using the changeset viewer.