source: libcfa/src/concurrency/kernel/fwd.hfa @ e873838

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since e873838 was e873838, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Removed unpark and added support for unpark from the kernel (removing the distinction between the two

  • Property mode set to 100644
File size: 4.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2020 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// kernel/fwd.hfa --
8//
9// Author           : Thierry Delisle
10// Created On       : Thu Jul 30 16:46:41 2020
11// Last Modified By :
12// Last Modified On :
13// Update Count     :
14//
15
16#pragma once
17
18#include "bits/defs.hfa"
19#include "bits/debug.hfa"
20
21#ifdef __cforall
22#include "bits/random.hfa"
23#endif
24
25struct $thread;
26struct processor;
27struct cluster;
28
29enum __Preemption_Reason { __NO_PREEMPTION, __ALARM_PREEMPTION, __POLL_PREEMPTION, __MANUAL_PREEMPTION };
30
31#define KERNEL_STORAGE(T,X) __attribute((aligned(__alignof__(T)))) static char storage_##X[sizeof(T)]
32
33#ifdef __cforall
34extern "C" {
35        extern "Cforall" {
36                extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
37                        struct $thread          * volatile this_thread;
38                        struct processor        * volatile this_processor;
39                        struct __processor_id_t * volatile this_proc_id;
40                        struct __stats_t        * volatile this_stats;
41
42                        struct {
43                                volatile unsigned short disable_count;
44                                volatile bool enabled;
45                                volatile bool in_progress;
46                        } preemption_state;
47
48                        #if defined(__SIZEOF_INT128__)
49                                __uint128_t rand_seed;
50                        #else
51                                uint64_t rand_seed;
52                        #endif
53                        struct {
54                                uint64_t fwd_seed;
55                                uint64_t bck_seed;
56                        } ready_rng;
57                } kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
58
59
60
61                static inline uint64_t __tls_rand() {
62                        #if defined(__SIZEOF_INT128__)
63                                return __lehmer64( kernelTLS.rand_seed );
64                        #else
65                                return __xorshift64( kernelTLS.rand_seed );
66                        #endif
67                }
68
69                #define M  (1_l64u << 48_l64u)
70                #define A  (25214903917_l64u)
71                #define AI (18446708753438544741_l64u)
72                #define C  (11_l64u)
73                #define D  (16_l64u)
74
75                static inline unsigned __tls_rand_fwd() {
76
77                        kernelTLS.ready_rng.fwd_seed = (A * kernelTLS.ready_rng.fwd_seed + C) & (M - 1);
78                        return kernelTLS.ready_rng.fwd_seed >> D;
79                }
80
81                static inline unsigned __tls_rand_bck() {
82                        unsigned int r = kernelTLS.ready_rng.bck_seed >> D;
83                        kernelTLS.ready_rng.bck_seed = AI * (kernelTLS.ready_rng.bck_seed - C) & (M - 1);
84                        return r;
85                }
86
87                #undef M
88                #undef A
89                #undef AI
90                #undef C
91                #undef D
92
93                static inline void __tls_rand_advance_bck(void) {
94                        kernelTLS.ready_rng.bck_seed = kernelTLS.ready_rng.fwd_seed;
95                }
96        }
97
98        #if 0 // def __ARM_ARCH
99                // function prototypes are only really used by these macros on ARM
100                void disable_global_interrupts();
101                void enable_global_interrupts();
102
103                #define TL_GET( member ) ( { __typeof__( kernelTLS.member ) target; \
104                        disable_global_interrupts(); \
105                        target = kernelTLS.member; \
106                        enable_global_interrupts(); \
107                        target; } )
108                #define TL_SET( member, value ) disable_global_interrupts(); \
109                        kernelTLS.member = value; \
110                        enable_global_interrupts();
111        #else
112                #define TL_GET( member ) kernelTLS.member
113                #define TL_SET( member, value ) kernelTLS.member = value;
114        #endif
115
116        extern void disable_interrupts();
117        extern void enable_interrupts_noPoll();
118        extern void enable_interrupts( __cfaabi_dbg_ctx_param );
119
120        extern "Cforall" {
121                extern void park( void );
122                extern void unpark( struct $thread * this );
123                static inline struct $thread * active_thread () { return TL_GET( this_thread ); }
124
125                extern bool force_yield( enum __Preemption_Reason );
126
127                static inline void yield() {
128                        force_yield(__MANUAL_PREEMPTION);
129                }
130
131                // Yield: yield N times
132                static inline void yield( unsigned times ) {
133                        for( times ) {
134                                yield();
135                        }
136                }
137
138                //-----------------------------------------------------------------------
139                // Statics call at the end of each thread to register statistics
140                #if !defined(__CFA_NO_STATISTICS__)
141                        static inline struct __stats_t * __tls_stats() {
142                                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
143                                /* paranoid */ verify( kernelTLS.this_stats );
144                                return kernelTLS.this_stats;
145                        }
146
147                        #define __STATS__(in_kernel, ...) { \
148                                if( !(in_kernel) ) disable_interrupts(); \
149                                with( *__tls_stats() ) { \
150                                        __VA_ARGS__ \
151                                } \
152                                if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \
153                        }
154                #else
155                        #define __STATS__(in_kernel, ...)
156                #endif
157        }
158}
159#endif
Note: See TracBrowser for help on using the repository browser.