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

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 be73f30 was e873838, checked in by Thierry Delisle <tdelisle@…>, 5 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
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;
[e660761]57 } kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
[3e2b9c9]58
[f2384c9a]59
60
[3e2b9c9]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 }
[f2384c9a]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 }
[e660761]96 }
97
[442b624]98 #if 0 // def __ARM_ARCH
[3e2b9c9]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();
[e660761]118 extern void enable_interrupts( __cfaabi_dbg_ctx_param );
119
[3e2b9c9]120 extern "Cforall" {
[e235429]121 extern void park( void );
122 extern void unpark( struct $thread * this );
[3e2b9c9]123 static inline struct $thread * active_thread () { return TL_GET( this_thread ); }
124
125 extern bool force_yield( enum __Preemption_Reason );
[e660761]126
[3e2b9c9]127 static inline void yield() {
128 force_yield(__MANUAL_PREEMPTION);
129 }
[e660761]130
[3e2b9c9]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 }
[e660761]158}
[442b624]159#endif
Note: See TracBrowser for help on using the repository browser.