Ignore:
Timestamp:
Nov 17, 2017, 10:56:16 AM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
cdbfab0
Parents:
f5c3b6c (diff), b7f8cb4 (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' into fix-bug-51

File:
1 edited

Legend:

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

    rf5c3b6c r0fe4e62  
    1414//
    1515
    16 #include <stdbool.h>
    17 #include <stdint.h>
     16#include "bits/defs.h"
     17#include "bits/locks.h"
    1818
    1919#ifdef __CFORALL__
     
    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        typedef void (*fptr_t)();
     28        typedef int_fast16_t __lock_size_t;
     29
     30        struct __thread_queue_t {
     31                struct thread_desc * head;
     32                struct thread_desc ** tail;
     33        };
     34
     35        struct __condition_stack_t {
     36                struct __condition_criterion_t * top;
     37        };
     38
     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 ** );
     45
     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
     51
     52        struct coStack_t {
     53                // size of stack
     54                size_t size;
     55
     56                // pointer to stack
     57                void *storage;
     58
     59                // stack grows towards stack limit
     60                void *limit;
     61
     62                // base of stack
     63                void *base;
     64
     65                // address of cfa_context_t
     66                void *context;
     67
     68                // address of top of storage
     69                void *top;
     70
     71                // whether or not the user allocated the stack
     72                bool userStack;
     73        };
     74
     75        enum coroutine_state { Halted, Start, Inactive, Active, Primed };
     76
     77        struct coroutine_desc {
     78                // stack information of the coroutine
     79                struct coStack_t stack;
     80
     81                // textual name for coroutine/task, initialized by uC++ generated code
     82                const char *name;
     83
     84                // copy of global UNIX variable errno
     85                int errno_;
     86
     87                // current execution status for coroutine
     88                enum coroutine_state state;
     89
     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;
    119159     };
    120160
    121161     #ifdef __CFORALL__
    122162     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
     163                static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
     164                        return this.list[index];
     165                }
     166
     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;
     171
     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                        }
     177
     178                        return true;
     179                }
     180        }
     181        #endif
    142182
    143183#endif //_INVOKE_H_
     
    146186#define _INVOKE_PRIVATE_H_
    147187
    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
     188        struct machine_context_t {
     189                void *SP;
     190                void *FP;
     191                void *PC;
     192        };
     193
     194        // assembler routines that performs the context switch
     195        extern void CtxInvokeStub( void );
     196        void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     197
     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
    169209
    170210#endif //_INVOKE_PRIVATE_H_
Note: See TracChangeset for help on using the changeset viewer.