Ignore:
File:
1 edited

Legend:

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

    rea7d2b0 r549c006  
    1414//
    1515
    16 #include "bits/defs.h"
    17 #include "bits/locks.h"
     16#include <stdbool.h>
     17#include <stdint.h>
    1818
    1919#ifdef __CFORALL__
     
    2525#define _INVOKE_H_
    2626
    27         typedef void (*fptr_t)();
    28         typedef int_fast16_t __lock_size_t;
     27      #define unlikely(x)    __builtin_expect(!!(x), 0)
     28      #define thread_local _Thread_local
    2929
    30         struct __thread_queue_t {
    31                 struct thread_desc * head;
    32                 struct thread_desc ** tail;
    33         };
     30      typedef void (*fptr_t)();
    3431
    35         struct __condition_stack_t {
    36                 struct __condition_criterion_t * top;
    37         };
     32      struct spinlock {
     33            volatile int lock;
     34            #ifdef __CFA_DEBUG__
     35                  const char * prev_name;
     36                  void* prev_thrd;
     37            #endif
     38      };
    3839
    39         #ifdef __CFORALL__
    40         extern "Cforall" {
    41                 void ?{}( struct __thread_queue_t & );
    42                 void append( struct __thread_queue_t &, struct thread_desc * );
    43                 struct thread_desc * pop_head( struct __thread_queue_t & );
    44                 struct thread_desc * remove( struct __thread_queue_t &, struct thread_desc ** );
     40      struct __thread_queue_t {
     41            struct thread_desc * head;
     42            struct thread_desc ** tail;
     43      };
    4544
    46                 void ?{}( struct __condition_stack_t & );
    47                 void push( struct __condition_stack_t &, struct __condition_criterion_t * );
    48                 struct __condition_criterion_t * pop( struct __condition_stack_t & );
    49         }
    50         #endif
     45      struct __condition_stack_t {
     46            struct __condition_criterion_t * top;
     47      };
    5148
    52         struct coStack_t {
    53                 // size of stack
    54                 size_t size;
     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 ** );
    5555
    56                 // pointer to stack
    57                 void *storage;
     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 * );
    5859
    59                 // stack grows towards stack limit
    60                 void *limit;
     60            void ?{}(spinlock & this);
     61            void ^?{}(spinlock & this);
     62      }
     63      #endif
    6164
    62                 // base of stack
    63                 void *base;
     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      };
    6474
    65                 // address of cfa_context_t
    66                 void *context;
     75      enum coroutine_state { Halted, Start, Inactive, Active, Primed };
    6776
    68                 // address of top of storage
    69                 void *top;
     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      };
    7085
    71                 // whether or not the user allocated the stack
    72                 bool userStack;
    73         };
     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      };
    7491
    75         enum coroutine_state { Halted, Start, Inactive, Active, Primed };
     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      };
    76101
    77         struct coroutine_desc {
    78                 // stack information of the coroutine
    79                 struct coStack_t stack;
     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      };
    80107
    81                 // textual name for coroutine/task, initialized by uC++ generated code
    82                 const char *name;
     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
    83114
    84                 // copy of global UNIX variable errno
    85                 int errno_;
     115            // Link lists fields
     116            struct thread_desc * next;                // instrusive link field for threads
    86117
    87                 // current execution status for coroutine
    88                 enum coroutine_state state;
    89118
    90                 // first coroutine to resume this one
    91                 struct coroutine_desc * starter;
    92 
    93                 // last coroutine to resume this one
    94                 struct coroutine_desc * last;
    95         };
    96 
    97         struct __waitfor_mask_t {
    98                 // the index of the accepted function, -1 if none
    99                 short * accepted;
    100 
    101                 // list of acceptable functions, null if any
    102                 struct __acceptable_t * clauses;
    103 
    104                 // number of acceptable functions
    105                 __lock_size_t size;
    106         };
    107 
    108         struct monitor_desc {
    109                 // spinlock to protect internal data
    110                 struct __spinlock_t lock;
    111 
    112                 // current owner of the monitor
    113                 struct thread_desc * owner;
    114 
    115                 // queue of threads that are blocked waiting for the monitor
    116                 struct __thread_queue_t entry_queue;
    117 
    118                 // stack of conditions to run next once we exit the monitor
    119                 struct __condition_stack_t signal_stack;
    120 
    121                 // monitor routines can be called recursively, we need to keep track of that
    122                 unsigned int recursion;
    123 
    124                 // mask used to know if some thread is waiting for something while holding the monitor
    125                 struct __waitfor_mask_t mask;
    126 
    127                 // node used to signal the dtor in a waitfor dtor
    128                 struct __condition_node_t * dtor_node;
    129         };
    130 
    131         struct __monitor_group_t {
    132                 // currently held monitors
    133                 struct monitor_desc ** list;
    134 
    135                 // number of currently held monitors
    136                 __lock_size_t size;
    137 
    138                 // last function that acquired monitors
    139                 fptr_t func;
    140         };
    141 
    142         struct thread_desc {
    143                 // Core threading fields
    144                 // coroutine body used to store context
    145                 struct coroutine_desc  self_cor;
    146 
    147                 // monitor body used for mutual exclusion
    148                 struct monitor_desc    self_mon;
    149 
    150                 // pointer to monitor with sufficient lifetime for current monitors
    151                 struct monitor_desc *  self_mon_p;
    152 
    153                 // monitors currently held by this thread
    154                 struct __monitor_group_t monitors;
    155 
    156                 // Link lists fields
    157                 // instrusive link field for threads
    158                 struct thread_desc * next;
    159119     };
    160120
    161121     #ifdef __CFORALL__
    162122     extern "Cforall" {
    163                 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    164                         return this.list[index];
    165                 }
     123            static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
     124                  return this.list[index];
     125            }
    166126
    167                 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
    168                         if( (lhs.list != 0) != (rhs.list != 0) ) return false;
    169                         if( lhs.size != rhs.size ) return false;
    170                         if( lhs.func != rhs.func ) return false;
     127            static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
     128                  if( (lhs.list != 0) != (rhs.list != 0) ) return false;
     129                  if( lhs.size != rhs.size ) return false;
     130                  if( lhs.func != rhs.func ) return false;
    171131
    172                         // Check that all the monitors match
    173                         for( int i = 0; i < lhs.size; i++ ) {
    174                                 // If not a match, check next function
    175                                 if( lhs[i] != rhs[i] ) return false;
    176                         }
     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                  }
    177137
    178                         return true;
    179                 }
    180         }
    181         #endif
     138                  return true;
     139            }
     140      }
     141      #endif
    182142
    183143#endif //_INVOKE_H_
     
    186146#define _INVOKE_PRIVATE_H_
    187147
    188         struct machine_context_t {
    189                 void *SP;
    190                 void *FP;
    191                 void *PC;
    192         };
     148      struct machine_context_t {
     149            void *SP;
     150            void *FP;
     151            void *PC;
     152      };
    193153
    194         // assembler routines that performs the context switch
    195         extern void CtxInvokeStub( void );
    196         void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     154      // assembler routines that performs the context switch
     155      extern void CtxInvokeStub( void );
     156      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
    197157
    198         #if   defined( __x86_64__ )
    199         #define CtxGet( ctx ) __asm__ ( \
    200                         "movq %%rsp,%0\n"   \
    201                         "movq %%rbp,%1\n"   \
    202                 : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    203         #elif defined( __i386__ )
    204         #define CtxGet( ctx ) __asm__ ( \
    205                         "movl %%esp,%0\n"   \
    206                         "movl %%ebp,%1\n"   \
    207                 : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    208         #endif
     158      #if   defined( __x86_64__ )
     159      #define CtxGet( ctx ) __asm__ ( \
     160                  "movq %%rsp,%0\n"   \
     161                  "movq %%rbp,%1\n"   \
     162            : "=rm" (ctx.SP), "=rm" (ctx.FP) )
     163      #elif defined( __i386__ )
     164      #define CtxGet( ctx ) __asm__ ( \
     165                  "movl %%esp,%0\n"   \
     166                  "movl %%ebp,%1\n"   \
     167            : "=rm" (ctx.SP), "=rm" (ctx.FP) )
     168      #endif
    209169
    210170#endif //_INVOKE_PRIVATE_H_
Note: See TracChangeset for help on using the changeset viewer.