source: libcfa/src/concurrency/kernel/fwd.hfa@ 1b5c3d60

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 1b5c3d60 was 8fc652e0, checked in by Thierry Delisle <tdelisle@…>, 5 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.