Changeset 6fa9e71 for src


Ignore:
Timestamp:
Nov 8, 2017, 10:58:43 AM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
8e0147a
Parents:
d06c808 (diff), b9d0fb6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
1 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • src/benchmark/Makefile.am

    rd06c808 r6fa9e71  
    2727
    2828noinst_PROGRAMS =
     29
     30all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
    2931
    3032bench$(EXEEXT) :
     
    6365ctxswitch-pthread$(EXEEXT):
    6466        @BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    65 
    66 ## =========================================================================================================
    67 creation$(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 
    74 creation-cfa_coroutine$(EXEEXT):
    75         ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    76 
    77 creation-cfa_thread$(EXEEXT):
    78         ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    79 
    80 creation-upp_coroutine$(EXEEXT):
    81         u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    82 
    83 creation-upp_thread$(EXEEXT):
    84         u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    85 
    86 creation-pthread$(EXEEXT):
    87         @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    8867
    8968## =========================================================================================================
     
    153132
    154133## =========================================================================================================
     134creation$(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
     141creation-cfa_coroutine$(EXEEXT):
     142        ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     143
     144creation-cfa_thread$(EXEEXT):
     145        ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     146
     147creation-upp_coroutine$(EXEEXT):
     148        u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     149
     150creation-upp_thread$(EXEEXT):
     151        u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     152
     153creation-pthread$(EXEEXT):
     154        @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     155
     156## =========================================================================================================
    155157
    156158%.run : %$(EXEEXT) ${REPEAT}
  • src/benchmark/Makefile.in

    rd06c808 r6fa9e71  
    444444.NOTPARALLEL:
    445445
     446all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
     447
    446448bench$(EXEEXT) :
    447449        @for ccflags in "-debug" "-nodebug"; do \
     
    479481        @BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    480482
    481 creation$(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 
    488 creation-cfa_coroutine$(EXEEXT):
    489         ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    490 
    491 creation-cfa_thread$(EXEEXT):
    492         ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    493 
    494 creation-upp_coroutine$(EXEEXT):
    495         u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    496 
    497 creation-upp_thread$(EXEEXT):
    498         u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    499 
    500 creation-pthread$(EXEEXT):
    501         @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    502 
    503483mutex$(EXEEXT) :\
    504484        mutex-function.run      \
     
    562542waitfor-cfa4$(EXEEXT):
    563543        ${CC}        schedext/cfa4.c     -DBENCH_N=500000      -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     544
     545creation$(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
     552creation-cfa_coroutine$(EXEEXT):
     553        ${CC}        creation/cfa_cor.c   -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     554
     555creation-cfa_thread$(EXEEXT):
     556        ${CC}        creation/cfa_thrd.c  -DBENCH_N=10000000   -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     557
     558creation-upp_coroutine$(EXEEXT):
     559        u++          creation/upp_cor.cc  -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     560
     561creation-upp_thread$(EXEEXT):
     562        u++          creation/upp_thrd.cc -DBENCH_N=50000000   -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     563
     564creation-pthread$(EXEEXT):
     565        @BACKEND_CC@ creation/pthreads.c  -DBENCH_N=250000     -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    564566
    565567%.run : %$(EXEEXT) ${REPEAT}
  • src/benchmark/csv-data.c

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    2525#define _INVOKE_H_
    2626
    27       #define unlikely(x)    __builtin_expect(!!(x), 0)
    28       #define thread_local _Thread_local
    29 
    30       typedef void (*fptr_t)();
    31 
    32       struct spinlock {
    33             volatile int lock;
    34             #ifdef __CFA_DEBUG__
    35                   const char * prev_name;
    36                   void* prev_thrd;
    37             #endif
    38       };
    39 
    40       struct __thread_queue_t {
    41             struct thread_desc * head;
    42             struct thread_desc ** tail;
    43       };
    44 
    45       struct __condition_stack_t {
    46             struct __condition_criterion_t * top;
    47       };
    48 
    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 ** );
    55 
    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 * );
    59 
    60             void ?{}(spinlock & this);
    61             void ^?{}(spinlock & this);
    62       }
    63       #endif
    64 
    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       };
    74 
    75       enum coroutine_state { Halted, Start, Inactive, Active, Primed };
    76 
    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       };
    85 
    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       };
    91 
    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       };
    101 
    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       };
    107 
    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
    114 
    115             // Link lists fields
    116             struct thread_desc * next;                // instrusive link field for threads
    117 
    118 
     27        #define unlikely(x)    __builtin_expect(!!(x), 0)
     28        #define thread_local _Thread_local
     29
     30        typedef void (*fptr_t)();
     31        typedef int_fast16_t __lock_size_t;
     32
     33        struct spinlock {
     34                volatile int lock;
     35                #ifdef __CFA_DEBUG__
     36                        const char * prev_name;
     37                        void* prev_thrd;
     38                #endif
     39        };
     40
     41        struct __thread_queue_t {
     42                struct thread_desc * head;
     43                struct thread_desc ** tail;
     44        };
     45
     46        struct __condition_stack_t {
     47                struct __condition_criterion_t * top;
     48        };
     49
     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 ** );
     56
     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 & );
     60
     61                void  ?{}(spinlock & this);
     62                void ^?{}(spinlock & this);
     63        }
     64        #endif
     65
     66        struct coStack_t {
     67                // size of stack
     68                size_t size;
     69
     70                // pointer to stack
     71                void *storage;
     72
     73                // stack grows towards stack limit
     74                void *limit;
     75
     76                // base of stack
     77                void *base;
     78
     79                // address of cfa_context_t
     80                void *context;
     81
     82                // address of top of storage
     83                void *top;
     84
     85                // whether or not the user allocated the stack
     86                bool userStack;
     87        };
     88
     89        enum coroutine_state { Halted, Start, Inactive, Active, Primed };
     90
     91        struct coroutine_desc {
     92                // stack information of the coroutine
     93                struct coStack_t stack;
     94
     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;
    119173     };
    120174
    121175     #ifdef __CFORALL__
    122176     extern "Cforall" {
    123             static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    124                   return this.list[index];
    125             }
    126 
    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;
    131 
    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                   }
    137 
    138                   return true;
    139             }
    140       }
    141       #endif
     177                static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
     178                        return this.list[index];
     179                }
     180
     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;
     185
     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                        }
     191
     192                        return true;
     193                }
     194        }
     195        #endif
    142196
    143197#endif //_INVOKE_H_
     
    146200#define _INVOKE_PRIVATE_H_
    147201
    148       struct machine_context_t {
    149             void *SP;
    150             void *FP;
    151             void *PC;
    152       };
    153 
    154       // assembler routines that performs the context switch
    155       extern void CtxInvokeStub( void );
    156       void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
    157 
    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
     202        struct machine_context_t {
     203                void *SP;
     204                void *FP;
     205                void *PC;
     206        };
     207
     208        // assembler routines that performs the context switch
     209        extern void CtxInvokeStub( void );
     210        void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     211
     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
    169223
    170224#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    rd06c808 r6fa9e71  
    2626//-----------------------------------------------------------------------------
    2727// Locks
    28 void lock      ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, spin if already acquired
    29 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, yield repeatedly if already acquired
    30 bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, return false if already acquired
    31 void unlock    ( spinlock * );                        // Unlock the spinlock
     28// Lock the spinlock, spin if already acquired
     29void lock      ( spinlock * DEBUG_CTX_PARAM2 );
     30
     31// Lock the spinlock, yield repeatedly if already acquired
     32void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
     33
     34// Lock the spinlock, return false if already acquired
     35bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
     36
     37// Unlock the spinlock
     38void unlock    ( spinlock * );
    3239
    3340struct semaphore {
     
    3946void  ?{}(semaphore & this, int count = 1);
    4047void ^?{}(semaphore & this);
    41 void P(semaphore * this);
    42 void V(semaphore * this);
     48void   P (semaphore & this);
     49void   V (semaphore & this);
    4350
    4451
     
    4653// Cluster
    4754struct cluster {
    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
     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;
    5163};
    5264
    53 void ?{}(cluster & this);
     65void ?{} (cluster & this);
    5466void ^?{}(cluster & this);
    5567
     
    7991struct processor {
    8092        // Main state
    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
     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;
    84101
    85102        // Termination
    86         volatile bool do_terminate;                     // Set to true to notify the processor should terminate
    87         semaphore terminated;                           // Termination synchronisation
     103        // Set to true to notify the processor should terminate
     104        volatile bool do_terminate;
     105
     106        // Termination synchronisation
     107        semaphore terminated;
    88108
    89109        // RunThread data
    90         struct FinishAction finish;                     // Action to do after a thread is ran
     110        // Action to do after a thread is ran
     111        struct FinishAction finish;
    91112
    92113        // Preemption data
    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
     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;
    95119
    96120#ifdef __CFA_DEBUG__
    97         char * last_enable;                             // Last function to enable preemption on this processor
     121        // Last function to enable preemption on this processor
     122        char * last_enable;
    98123#endif
    99124};
    100125
    101 void ?{}(processor & this);
    102 void ?{}(processor & this, cluster * cltr);
     126void  ?{}(processor & this);
     127void  ?{}(processor & this, cluster * cltr);
    103128void ^?{}(processor & this);
    104129
  • src/libcfa/concurrency/kernel.c

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    3939}
    4040
    41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
    42 //      return ((intptr_t)lhs) < ((intptr_t)rhs);
    43 // }
    44 
    4541struct monitor_guard_t {
    4642        monitor_desc ** m;
    47         int count;
     43        __lock_size_t  count;
    4844        monitor_desc ** prev_mntrs;
    49         unsigned short  prev_count;
     45        __lock_size_t   prev_count;
    5046        fptr_t          prev_func;
    5147};
    5248
    53 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
     49void ?{}( monitor_guard_t & this, monitor_desc ** m, __lock_size_t count, void (*func)() );
    5450void ^?{}( monitor_guard_t & this );
    5551
     
    5753        monitor_desc * m;
    5854        monitor_desc ** prev_mntrs;
    59         unsigned short  prev_count;
     55        __lock_size_t   prev_count;
    6056        fptr_t          prev_func;
    6157};
     
    7470
    7571struct __condition_criterion_t {
    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
     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;
    8083};
    8184
    8285struct __condition_node_t {
    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
     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;
    88100};
    89101
     
    93105};
    94106
    95 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info );
     107void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info );
    96108void ?{}(__condition_criterion_t & this );
    97109void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner );
    98110
    99111void ?{}( __condition_blocked_queue_t & );
    100 void append( __condition_blocked_queue_t *, __condition_node_t * );
    101 __condition_node_t * pop_head( __condition_blocked_queue_t * );
     112void append( __condition_blocked_queue_t &, __condition_node_t * );
     113__condition_node_t * pop_head( __condition_blocked_queue_t & );
    102114
    103115struct condition {
    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
     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;
    107124};
    108125
     
    116133}
    117134
    118 void wait( condition * this, uintptr_t user_info = 0 );
    119 bool signal( condition * this );
    120 bool signal_block( condition * this );
    121 static inline bool is_empty( condition * this ) { return !this->blocked.head; }
    122 uintptr_t front( condition * this );
     135              void wait        ( condition & this, uintptr_t user_info = 0 );
     136              bool signal      ( condition & this );
     137              bool signal_block( condition & this );
     138static inline bool is_empty    ( condition & this ) { return !this.blocked.head; }
     139         uintptr_t front       ( condition & this );
    123140
    124141//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor.c

    rd06c808 r6fa9e71  
    2626// Forward declarations
    2727static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    28 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner );
    29 static inline void set_mask  ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
     28static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );
     29static inline void set_mask  ( monitor_desc * storage [], __lock_size_t 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, unsigned short count );
    36 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
    37 static inline void unlock_all( spinlock ** locks, unsigned short count );
    38 static inline void unlock_all( monitor_desc ** locks, unsigned short count );
    39 
    40 static inline void save   ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks );
    41 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks );
    42 
    43 static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    44 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     35static inline void lock_all  ( spinlock * locks [], __lock_size_t count );
     36static inline void lock_all  ( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count );
     37static inline void unlock_all( spinlock * locks [], __lock_size_t count );
     38static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );
     39
     40static inline void save   ( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
     41static inline void restore( monitor_desc * ctx [], __lock_size_t count, spinlock * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
     42
     43static inline void init     ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     44static inline void init_push( __lock_size_t 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, int count );
     47static inline void                 brand_condition   ( condition & );
     48static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );
    4949
    5050forall(dtype T | sized( T ))
    51 static inline short insert_unique( T ** array, short & size, T * val );
    52 static inline short count_max    ( const __waitfor_mask_t & mask );
    53 static inline short aggregate    ( monitor_desc ** storage, const __waitfor_mask_t & mask );
     51static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );
     52static inline __lock_size_t count_max    ( const __waitfor_mask_t & mask );
     53static inline __lock_size_t 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         unsigned short count = cnt;                               /* Save the count to a local variable                                                  */ \
     69        __lock_size_t 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                 int count = 1;
     155                __lock_size_t 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(int i = 0; i < monitors.size; i++) {
     274        for( __lock_size_t 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, int count) {
    282         for(int i = count - 1; i >= 0; i--) {
     281static inline void leave(monitor_desc * monitors [], __lock_size_t count) {
     282        for( __lock_size_t 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, int count, fptr_t func ) {
     289void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
    290290        // Store current array
    291291        this.m = m;
     
    296296
    297297        // Save previous thread context
    298         this.prev_mntrs = this_thread->monitors.list;
    299         this.prev_count = this_thread->monitors.size;
    300         this.prev_func  = this_thread->monitors.func;
     298        this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
    301299
    302300        // Update thread context (needed for conditions)
    303         this_thread->monitors.list = m;
    304         this_thread->monitors.size = count;
    305         this_thread->monitors.func = func;
     301        this_thread->monitors.[list, size, func] = [m, count, func];
    306302
    307303        // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     
    325321
    326322        // Restore thread context
    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 
     323        this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     324}
    332325
    333326// Ctor for monitor guard
    334327// Sorts monitors before entering
    335 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
     328void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
    336329        // Store current array
    337330        this.m = *m;
    338331
    339332        // Save previous thread context
    340         this.prev_mntrs = this_thread->monitors.list;
    341         this.prev_count = this_thread->monitors.size;
    342         this.prev_func  = this_thread->monitors.func;
     333        this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
    343334
    344335        // Update thread context (needed for conditions)
    345         this_thread->monitors.list = m;
    346         this_thread->monitors.size = 1;
    347         this_thread->monitors.func = func;
     336        this_thread->monitors.[list, size, func] = [m, 1, func];
    348337
    349338        __enter_monitor_dtor( this.m, func );
    350339}
    351 
    352340
    353341// Dtor for monitor guard
     
    357345
    358346        // Restore thread context
    359         this_thread->monitors.list = this.prev_mntrs;
    360         this_thread->monitors.size = this.prev_count;
    361         this_thread->monitors.func = this.prev_func;
     347        this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
    362348}
    363349
    364350//-----------------------------------------------------------------------------
    365351// Internal scheduling types
    366 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
     352void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
    367353        this.waiting_thread = waiting_thread;
    368354        this.count = count;
     
    378364}
    379365
    380 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ) {
     366void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) {
    381367        this.ready  = false;
    382368        this.target = target;
    383         this.owner  = owner;
     369        this.owner  = &owner;
    384370        this.next   = NULL;
    385371}
     
    387373//-----------------------------------------------------------------------------
    388374// Internal scheduling
    389 void wait( condition * this, uintptr_t user_info = 0 ) {
     375void wait( condition & this, uintptr_t user_info = 0 ) {
    390376        brand_condition( this );
    391377
    392378        // Check that everything is as expected
    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 );
     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 );
    396382
    397383        // Create storage for monitor context
    398         monitor_ctx( this->monitors, this->monitor_count );
     384        monitor_ctx( this.monitors, this.monitor_count );
    399385
    400386        // Create the node specific to this wait operation
     
    403389        // Append the current wait operation to the ones already queued on the condition
    404390        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
    405         append( &this->blocked, &waiter );
     391        append( this.blocked, &waiter );
    406392
    407393        // Lock all monitors (aggregates the locks as well)
     
    409395
    410396        // Find the next thread(s) to run
    411         short thread_count = 0;
     397        __lock_size_t thread_count = 0;
    412398        thread_desc * threads[ count ];
    413399        __builtin_memset( threads, 0, sizeof( threads ) );
     
    417403
    418404        // Remove any duplicate threads
    419         for( int i = 0; i < count; i++) {
     405        for( __lock_size_t i = 0; i < count; i++) {
    420406                thread_desc * new_owner = next_thread( monitors[i] );
    421407                insert_unique( threads, thread_count, new_owner );
     
    429415}
    430416
    431 bool signal( condition * this ) {
     417bool signal( condition & this ) {
    432418        if( is_empty( this ) ) { return false; }
    433419
    434420        //Check that everything is as expected
    435         verify( this->monitors );
    436         verify( this->monitor_count != 0 );
     421        verify( this.monitors );
     422        verify( this.monitor_count != 0 );
    437423
    438424        //Some more checking in debug
    439425        LIB_DEBUG_DO(
    440426                thread_desc * this_thrd = this_thread;
    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] );
     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] );
    448434                        }
    449435                }
    450436        );
    451437
    452         unsigned short count = this->monitor_count;
     438        __lock_size_t count = this.monitor_count;
    453439
    454440        // Lock all monitors
    455         lock_all( this->monitors, NULL, count );
     441        lock_all( this.monitors, NULL, count );
    456442
    457443        //Pop the head of the waiting queue
    458         __condition_node_t * node = pop_head( &this->blocked );
     444        __condition_node_t * node = pop_head( this.blocked );
    459445
    460446        //Add the thread to the proper AS stack
     
    462448                __condition_criterion_t * crit = &node->criteria[i];
    463449                assert( !crit->ready );
    464                 push( &crit->target->signal_stack, crit );
     450                push( crit->target->signal_stack, crit );
    465451        }
    466452
    467453        //Release
    468         unlock_all( this->monitors, count );
     454        unlock_all( this.monitors, count );
    469455
    470456        return true;
    471457}
    472458
    473 bool signal_block( condition * this ) {
    474         if( !this->blocked.head ) { return false; }
     459bool signal_block( condition & this ) {
     460        if( !this.blocked.head ) { return false; }
    475461
    476462        //Check that everything is as expected
    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 );
     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 );
    479465
    480466        // Create storage for monitor context
    481         monitor_ctx( this->monitors, this->monitor_count );
     467        monitor_ctx( this.monitors, this.monitor_count );
    482468
    483469        // Lock all monitors (aggregates the locks them as well)
     
    491477
    492478        //Find the thread to run
    493         thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
     479        thread_desc * signallee = pop_head( this.blocked )->waiting_thread;
    494480        set_owner( monitors, count, signallee );
    495481
    496         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );
     482        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
    497483
    498484        //Everything is ready to go to sleep
     
    512498
    513499// Access the user_info of the thread waiting at the front of the queue
    514 uintptr_t front( condition * this ) {
     500uintptr_t front( condition & this ) {
    515501        verifyf( !is_empty(this),
    516502                "Attempt to access user data on an empty condition.\n"
    517503                "Possible cause is not checking if the condition is empty before reading stored data."
    518504        );
    519         return this->blocked.head->user_info;
     505        return this.blocked.head->user_info;
    520506}
    521507
     
    537523        // This statment doesn't have a contiguous list of monitors...
    538524        // Create one!
    539         short max = count_max( mask );
     525        __lock_size_t max = count_max( mask );
    540526        monitor_desc * mon_storage[max];
    541527        __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    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);
     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);
    545531
    546532        if(actual_count == 0) return;
     
    569555
    570556                                __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    571                                 push( &mon2dtor->signal_stack, dtor_crit );
     557                                push( mon2dtor->signal_stack, dtor_crit );
    572558
    573559                                unlock_all( locks, count );
     
    629615        set_mask( monitors, count, mask );
    630616
    631         for(int i = 0; i < count; i++) {
     617        for( __lock_size_t i = 0; i < count; i++) {
    632618                verify( monitors[i]->owner == this_thread );
    633619        }
     
    661647}
    662648
    663 static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {
     649static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {
    664650        monitors[0]->owner     = owner;
    665651        monitors[0]->recursion = 1;
    666         for( int i = 1; i < count; i++ ) {
     652        for( __lock_size_t i = 1; i < count; i++ ) {
    667653                monitors[i]->owner     = owner;
    668654                monitors[i]->recursion = 0;
     
    670656}
    671657
    672 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
    673         for(int i = 0; i < count; i++) {
     658static 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++) {
    674660                storage[i]->mask = mask;
    675661        }
     
    685671        //Check the signaller stack
    686672        LIB_DEBUG_PRINT_SAFE("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
    687         __condition_criterion_t * urgent = pop( &this->signal_stack );
     673        __condition_criterion_t * urgent = pop( this->signal_stack );
    688674        if( urgent ) {
    689675                //The signaller stack is not empty,
     
    697683        // No signaller thread
    698684        // Get the next thread in the entry_queue
    699         thread_desc * new_owner = pop_head( &this->entry_queue );
     685        thread_desc * new_owner = pop_head( this->entry_queue );
    700686        set_owner( this, new_owner );
    701687
     
    705691static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    706692        __acceptable_t * it = this->mask.clauses; // Optim
    707         int count = this->mask.size;
     693        __lock_size_t count = this->mask.size;
    708694
    709695        // Check if there are any acceptable functions
     
    714700
    715701        // For all acceptable functions check if this is the current function.
    716         for( short i = 0; i < count; i++, it++ ) {
     702        for( __lock_size_t i = 0; i < count; i++, it++ ) {
    717703                if( *it == group ) {
    718704                        *this->mask.accepted = i;
     
    725711}
    726712
    727 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
    728         for(int i = 0; i < count; i++) {
     713static 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++) {
    729715                (criteria[i]){ monitors[i], waiter };
    730716        }
    731717
    732         waiter->criteria = criteria;
    733 }
    734 
    735 static 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++) {
     718        waiter.criteria = criteria;
     719}
     720
     721static 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++) {
    737723                (criteria[i]){ monitors[i], waiter };
    738724                LIB_DEBUG_PRINT_SAFE( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
    739                 push( &criteria[i].target->signal_stack, &criteria[i] );
    740         }
    741 
    742         waiter->criteria = criteria;
    743 }
    744 
    745 static inline void lock_all( spinlock ** locks, unsigned short count ) {
    746         for( int i = 0; i < count; i++ ) {
     725                push( criteria[i].target->signal_stack, &criteria[i] );
     726        }
     727
     728        waiter.criteria = criteria;
     729}
     730
     731static inline void lock_all( spinlock * locks [], __lock_size_t count ) {
     732        for( __lock_size_t i = 0; i < count; i++ ) {
    747733                lock_yield( locks[i] DEBUG_CTX2 );
    748734        }
    749735}
    750736
    751 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) {
    752         for( int i = 0; i < count; i++ ) {
     737static inline void lock_all( monitor_desc * source [], spinlock * /*out*/ locks [], __lock_size_t count ) {
     738        for( __lock_size_t i = 0; i < count; i++ ) {
    753739                spinlock * l = &source[i]->lock;
    754740                lock_yield( l DEBUG_CTX2 );
     
    757743}
    758744
    759 static inline void unlock_all( spinlock ** locks, unsigned short count ) {
    760         for( int i = 0; i < count; i++ ) {
     745static inline void unlock_all( spinlock * locks [], __lock_size_t count ) {
     746        for( __lock_size_t i = 0; i < count; i++ ) {
    761747                unlock( locks[i] );
    762748        }
    763749}
    764750
    765 static inline void unlock_all( monitor_desc ** locks, unsigned short count ) {
    766         for( int i = 0; i < count; i++ ) {
     751static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) {
     752        for( __lock_size_t i = 0; i < count; i++ ) {
    767753                unlock( &locks[i]->lock );
    768754        }
    769755}
    770756
    771 static 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++ ) {
     757static 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++ ) {
    773765                recursions[i] = ctx[i]->recursion;
    774766                masks[i]      = ctx[i]->mask;
     
    776768}
    777769
    778 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
     770static 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) {
    779777        lock_all( locks, count );
    780         for( int i = 0; i < count; i++ ) {
     778        for( __lock_size_t i = 0; i < count; i++ ) {
    781779                ctx[i]->recursion = recursions[i];
    782780                ctx[i]->mask      = masks[i];
     
    811809}
    812810
    813 static inline void brand_condition( condition * this ) {
     811static inline void brand_condition( condition & this ) {
    814812        thread_desc * thrd = this_thread;
    815         if( !this->monitors ) {
     813        if( !this.monitors ) {
    816814                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    817815                assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
    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 
    827 static 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;
     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
     825static 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;
    830828
    831829        // For each thread in the entry-queue
    832         for(    thread_desc ** thrd_it = &entry_queue->head;
     830        for(    thread_desc ** thrd_it = &entry_queue.head;
    833831                *thrd_it;
    834832                thrd_it = &(*thrd_it)->next
     
    852850
    853851forall(dtype T | sized( T ))
    854 static inline short insert_unique( T ** array, short & size, T * val ) {
     852static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) {
    855853        if( !val ) return size;
    856854
    857         for(int i = 0; i <= size; i++) {
     855        for( __lock_size_t i = 0; i <= size; i++) {
    858856                if( array[i] == val ) return size;
    859857        }
     
    864862}
    865863
    866 static inline short count_max( const __waitfor_mask_t & mask ) {
    867         short max = 0;
    868         for( int i = 0; i < mask.size; i++ ) {
     864static 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++ ) {
    869867                max += mask.clauses[i].size;
    870868        }
     
    872870}
    873871
    874 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
    875         short size = 0;
    876         for( int i = 0; i < mask.size; i++ ) {
     872static 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++ ) {
    877875                __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size );
    878                 for( int j = 0; j < mask.clauses[i].size; j++) {
     876                for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {
    879877                        insert_unique( storage, size, mask.clauses[i].list[j] );
    880878                }
     
    890888}
    891889
    892 void 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;
     890void 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;
    900898        if( head ) {
    901                 this->head = head->next;
     899                this.head = head->next;
    902900                if( !head->next ) {
    903                         this->tail = &this->head;
     901                        this.tail = &this.head;
    904902                }
    905903                head->next = NULL;
  • src/tests/boundedBuffer.c

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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 
    21 bool empty( condition & c ) {
    22         return c.blocked.head == NULL;
    23 }
    2420
    2521enum { NoOfPairs = 20 };
     
    3127
    3228unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
    33         if ( empty( ds.Boys[ccode] ) ) {
    34                 wait( &ds.Girls[ccode] );
     29        if ( is_empty( ds.Boys[ccode] ) ) {
     30                wait( ds.Girls[ccode] );
    3531                ds.GirlPhoneNo = PhoneNo;
    3632        } else {
    3733                ds.GirlPhoneNo = PhoneNo;
    38                 signal_block( &ds.Boys[ccode] );
     34                signal_block( ds.Boys[ccode] );
    3935        } // if
    4036        return ds.BoyPhoneNo;
     
    4238
    4339unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
    44         if ( empty( ds.Girls[ccode] ) ) {
    45                 wait( &ds.Boys[ccode] );
     40        if ( is_empty( ds.Girls[ccode] ) ) {
     41                wait( ds.Boys[ccode] );
    4642                ds.BoyPhoneNo = PhoneNo;
    4743        } else {
    4844                ds.BoyPhoneNo = PhoneNo;
    49                 signal_block( &ds.Girls[ccode] );
     45                signal_block( ds.Girls[ccode] );
    5046        } // if
    5147        return ds.GirlPhoneNo;
  • src/tests/sched-int-barge.c

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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

    rd06c808 r6fa9e71  
    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.