source: libcfa/src/concurrency/kernel/fwd.hfa @ 685810e

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

Change usage of TLS to more strongly segregate in kernel and out of kernel usage.

  • Property mode set to 100644
File size: 4.2 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                } __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" )));
58
59                extern bool __preemption_enabled();
60
61                static inline KernelThreadData & kernelTLS( void ) {
62                        /* paranoid */ verify( ! __preemption_enabled() );
63                        return __cfaabi_tls;
64                }
65
66                extern uintptr_t __cfatls_get( unsigned long int member );
67                // #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
68                #define publicTLS_get( member ) (__cfaabi_tls.member)
69                // extern forall(otype T) T __cfatls_get( T * member, T value );
70                // #define publicTLS_set( member, value ) __cfatls_set( (typeof(member)*)__builtin_offsetof(KernelThreadData, member), value );
71
72                static inline uint64_t __tls_rand() {
73                        #if defined(__SIZEOF_INT128__)
74                                return __lehmer64( kernelTLS().rand_seed );
75                        #else
76                                return __xorshift64( kernelTLS().rand_seed );
77                        #endif
78                }
79
80                #define M  (1_l64u << 48_l64u)
81                #define A  (25214903917_l64u)
82                #define AI (18446708753438544741_l64u)
83                #define C  (11_l64u)
84                #define D  (16_l64u)
85
86                static inline unsigned __tls_rand_fwd() {
87
88                        kernelTLS().ready_rng.fwd_seed = (A * kernelTLS().ready_rng.fwd_seed + C) & (M - 1);
89                        return kernelTLS().ready_rng.fwd_seed >> D;
90                }
91
92                static inline unsigned __tls_rand_bck() {
93                        unsigned int r = kernelTLS().ready_rng.bck_seed >> D;
94                        kernelTLS().ready_rng.bck_seed = AI * (kernelTLS().ready_rng.bck_seed - C) & (M - 1);
95                        return r;
96                }
97
98                #undef M
99                #undef A
100                #undef AI
101                #undef C
102                #undef D
103
104                static inline void __tls_rand_advance_bck(void) {
105                        kernelTLS().ready_rng.bck_seed = kernelTLS().ready_rng.fwd_seed;
106                }
107        }
108
109
110
111        extern void disable_interrupts();
112        extern void enable_interrupts_noPoll();
113        extern void enable_interrupts( __cfaabi_dbg_ctx_param );
114
115        extern "Cforall" {
116                extern void park( void );
117                extern void unpark( struct $thread * this );
118                static inline struct $thread * active_thread () {
119                        struct $thread * t = publicTLS_get( this_thread );
120                        /* paranoid */ verify( t );
121                        return t;
122                }
123
124                extern bool force_yield( enum __Preemption_Reason );
125
126                static inline void yield() {
127                        force_yield(__MANUAL_PREEMPTION);
128                }
129
130                // Yield: yield N times
131                static inline void yield( unsigned times ) {
132                        for( times ) {
133                                yield();
134                        }
135                }
136
137                //-----------------------------------------------------------------------
138                // Statics call at the end of each thread to register statistics
139                #if !defined(__CFA_NO_STATISTICS__)
140                        static inline struct __stats_t * __tls_stats() {
141                                /* paranoid */ verify( ! __preemption_enabled() );
142                                /* paranoid */ verify( kernelTLS().this_stats );
143                                return kernelTLS().this_stats;
144                        }
145
146                        #define __STATS__(in_kernel, ...) { \
147                                if( !(in_kernel) ) disable_interrupts(); \
148                                with( *__tls_stats() ) { \
149                                        __VA_ARGS__ \
150                                } \
151                                if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \
152                        }
153                #else
154                        #define __STATS__(in_kernel, ...)
155                #endif
156        }
157}
158#endif
Note: See TracBrowser for help on using the repository browser.