Ignore:
Timestamp:
Nov 6, 2017, 11:11:56 AM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
a2ea829
Parents:
e706bfd (diff), 121ac13 (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:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/invoke.h

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