source: libcfa/src/concurrency/kernel/fwd.hfa @ 58fe85a

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

Added function thread_rand as a tls-safe version of tls_rand()

  • Property mode set to 100644
File size: 4.0 KB
RevLine 
[e660761]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
[3e2b9c9]16#pragma once
17
[e660761]18#include "bits/defs.hfa"
19#include "bits/debug.hfa"
20
[3e2b9c9]21#ifdef __cforall
22#include "bits/random.hfa"
[e660761]23#endif
24
25struct $thread;
26struct processor;
27struct cluster;
28
[3e2b9c9]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
[e660761]33#ifdef __cforall
34extern "C" {
[3e2b9c9]35        extern "Cforall" {
[e660761]36                extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
[e873838]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;
[e660761]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
[f2384c9a]53                        struct {
54                                uint64_t fwd_seed;
55                                uint64_t bck_seed;
56                        } ready_rng;
[8fc652e0]57                } __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" )));
[3e2b9c9]58
[8fc652e0]59                extern bool __preemption_enabled();
[f2384c9a]60
[8fc652e0]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 );
[82a2fed]67                #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
[f2384c9a]68
[3e2b9c9]69                static inline uint64_t __tls_rand() {
70                        #if defined(__SIZEOF_INT128__)
[8fc652e0]71                                return __lehmer64( kernelTLS().rand_seed );
[3e2b9c9]72                        #else
[8fc652e0]73                                return __xorshift64( kernelTLS().rand_seed );
[3e2b9c9]74                        #endif
75                }
[f2384c9a]76
77                #define M  (1_l64u << 48_l64u)
78                #define A  (25214903917_l64u)
79                #define AI (18446708753438544741_l64u)
80                #define C  (11_l64u)
81                #define D  (16_l64u)
82
83                static inline unsigned __tls_rand_fwd() {
84
[8fc652e0]85                        kernelTLS().ready_rng.fwd_seed = (A * kernelTLS().ready_rng.fwd_seed + C) & (M - 1);
86                        return kernelTLS().ready_rng.fwd_seed >> D;
[f2384c9a]87                }
88
89                static inline unsigned __tls_rand_bck() {
[8fc652e0]90                        unsigned int r = kernelTLS().ready_rng.bck_seed >> D;
91                        kernelTLS().ready_rng.bck_seed = AI * (kernelTLS().ready_rng.bck_seed - C) & (M - 1);
[f2384c9a]92                        return r;
93                }
94
95                #undef M
96                #undef A
97                #undef AI
98                #undef C
99                #undef D
100
101                static inline void __tls_rand_advance_bck(void) {
[8fc652e0]102                        kernelTLS().ready_rng.bck_seed = kernelTLS().ready_rng.fwd_seed;
[f2384c9a]103                }
[e660761]104        }
105
[8fc652e0]106
[3e2b9c9]107
108        extern void disable_interrupts();
109        extern void enable_interrupts_noPoll();
[e660761]110        extern void enable_interrupts( __cfaabi_dbg_ctx_param );
111
[3e2b9c9]112        extern "Cforall" {
[e235429]113                extern void park( void );
114                extern void unpark( struct $thread * this );
[8fc652e0]115                static inline struct $thread * active_thread () {
116                        struct $thread * t = publicTLS_get( this_thread );
117                        /* paranoid */ verify( t );
118                        return t;
119                }
[3e2b9c9]120
121                extern bool force_yield( enum __Preemption_Reason );
[e660761]122
[3e2b9c9]123                static inline void yield() {
124                        force_yield(__MANUAL_PREEMPTION);
125                }
[e660761]126
[3e2b9c9]127                // Yield: yield N times
128                static inline void yield( unsigned times ) {
129                        for( times ) {
130                                yield();
131                        }
132                }
133
[fe9468e2]134                extern uint64_t thread_rand();
135
[3e2b9c9]136                //-----------------------------------------------------------------------
137                // Statics call at the end of each thread to register statistics
138                #if !defined(__CFA_NO_STATISTICS__)
139                        static inline struct __stats_t * __tls_stats() {
[8fc652e0]140                                /* paranoid */ verify( ! __preemption_enabled() );
141                                /* paranoid */ verify( kernelTLS().this_stats );
142                                return kernelTLS().this_stats;
[3e2b9c9]143                        }
144
145                        #define __STATS__(in_kernel, ...) { \
146                                if( !(in_kernel) ) disable_interrupts(); \
147                                with( *__tls_stats() ) { \
148                                        __VA_ARGS__ \
149                                } \
150                                if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \
151                        }
152                #else
153                        #define __STATS__(in_kernel, ...)
154                #endif
155        }
[e660761]156}
[442b624]157#endif
Note: See TracBrowser for help on using the repository browser.