source: src/libcfa/concurrency/invoke.h @ 3edc2df

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 3edc2df was c1a9c86, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Used fast_int in more data structure and started using tuple assign

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[8def349]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// invoke.h --
8//
9// Author           : Thierry Delisle
10// Created On       : Tue Jan 17 12:27:26 2016
[6b0b624]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Jul 21 22:28:56 2017
13// Update Count     : 1
[8def349]14//
15
[5c81105]16#include <stdbool.h>
17#include <stdint.h>
[78b3f52]18
[5c81105]19#ifdef __CFORALL__
20extern "C" {
21#endif
22
23#if ! defined(__CFA_INVOKE_PRIVATE__)
[78b3f52]24#ifndef _INVOKE_H_
25#define _INVOKE_H_
26
[025278e]27        #define unlikely(x)    __builtin_expect(!!(x), 0)
28        #define thread_local _Thread_local
[90c4df0]29
[025278e]30        typedef void (*fptr_t)();
[513daec]31        typedef int_fast16_t __lock_size_t;
[b18830e]32
[025278e]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
[c1a9c86]68                size_t size;
[025278e]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
[c1a9c86]119                __lock_size_t size;
[025278e]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
[c1a9c86]150                __lock_size_t size;
[025278e]151
152                // last function that acquired monitors
[c1a9c86]153                fptr_t func;
[025278e]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;
[97e3296]173     };
[8118303]174
[b18830e]175     #ifdef __CFORALL__
176     extern "Cforall" {
[025278e]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
[b18830e]196
[5c81105]197#endif //_INVOKE_H_
198#else //! defined(__CFA_INVOKE_PRIVATE__)
199#ifndef _INVOKE_PRIVATE_H_
200#define _INVOKE_PRIVATE_H_
[b227f68]201
[025278e]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
[78b3f52]223
[5c81105]224#endif //_INVOKE_PRIVATE_H_
225#endif //! defined(__CFA_INVOKE_PRIVATE__)
226#ifdef __CFORALL__
227}
228#endif
[6b0b624]229
230// Local Variables: //
231// mode: c //
232// tab-width: 4 //
233// End: //
Note: See TracBrowser for help on using the repository browser.