source: libcfa/src/concurrency/kernel_private.hfa@ 2649ff9

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum stuck-waitfor-destruct
Last change on this file since 2649ff9 was 9b1dcc2, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Changed scheduling API to adapt to non-Processors scheduling threads.

  • Property mode set to 100644
File size: 8.1 KB
RevLine 
[75f3522]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 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//
[73abe95]7// kernel_private.hfa --
[75f3522]8//
9// Author : Thierry Delisle
10// Created On : Mon Feb 13 12:27:26 2017
[6b0b624]11// Last Modified By : Peter A. Buhr
[1805b1b]12// Last Modified On : Sat Nov 30 19:25:02 2019
13// Update Count : 8
[75f3522]14//
15
[6b0b624]16#pragma once
[75f3522]17
[58b6d1b]18#include "kernel.hfa"
19#include "thread.hfa"
[75f3522]20
[73abe95]21#include "alarm.hfa"
[fa21ac9]22
[4aa2fb2]23
[75f3522]24//-----------------------------------------------------------------------------
25// Scheduler
[1c273d0]26
[9b1dcc2]27struct __attribute__((aligned(64))) __scheduler_lock_id_t;
28
[1c273d0]29extern "C" {
[2026bb6]30 void disable_interrupts() OPTIONAL_THREAD;
[969b3fe]31 void enable_interrupts_noPoll();
[36982fc]32 void enable_interrupts( __cfaabi_dbg_ctx_param );
[1c273d0]33}
34
[9b1dcc2]35void __schedule_thread( struct __processor_id_t *, $thread * ) __attribute__((nonnull (2)));
[75f3522]36
[e60e0dc]37//Block current thread and release/wake-up the following resources
[b0c7419]38void __leave_thread() __attribute__((noreturn));
[db6f06a]39
[75f3522]40//-----------------------------------------------------------------------------
41// Processor
42void main(processorCtx_t *);
[85b1deb]43
[8c50aed]44void * __create_pthread( pthread_t *, void * (*)(void *), void * );
[1805b1b]45
[85b1deb]46
[75f3522]47
[e60e0dc]48struct event_kernel_t {
[fa21ac9]49 alarm_list_t alarms;
[ea7d2b0]50 __spinlock_t lock;
[fa21ac9]51};
52
[e60e0dc]53extern event_kernel_t * event_kernel;
54
[d8548e2]55struct __cfa_kernel_preemption_state_t {
[b69ea6b]56 bool enabled;
57 bool in_progress;
58 unsigned short disable_count;
59};
60
[afc2427]61extern volatile thread_local __cfa_kernel_preemption_state_t preemption_state __attribute__ ((tls_model ( "initial-exec" )));
[c81ebf9]62
[6502a2b]63extern cluster * mainCluster;
64
[75f3522]65//-----------------------------------------------------------------------------
66// Threads
67extern "C" {
[c7a900a]68 void __cfactx_invoke_thread(void (*main)(void *), void * this);
[75f3522]69}
70
[f7d6bb0]71__cfaabi_dbg_debug_do(
[ac2b598]72 extern void __cfaabi_dbg_thread_register ( $thread * thrd );
73 extern void __cfaabi_dbg_thread_unregister( $thread * thrd );
[f7d6bb0]74)
75
[2d8f7b0]76// KERNEL ONLY unpark with out disabling interrupts
[9b1dcc2]77void __unpark( struct __processor_id_t *, $thread * thrd __cfaabi_dbg_ctx_param2 );
[2d8f7b0]78
[92976d9]79//-----------------------------------------------------------------------------
80// I/O
[dd4e2d7]81void __kernel_io_startup ( cluster &, unsigned, bool );
[f6660520]82void __kernel_io_finish_start( cluster & );
83void __kernel_io_prepare_stop( cluster & );
84void __kernel_io_shutdown ( cluster &, bool );
[92976d9]85
[969b3fe]86//-----------------------------------------------------------------------------
87// Utils
[7768b8d]88#define KERNEL_STORAGE(T,X) __attribute((aligned(__alignof__(T)))) static char storage_##X[sizeof(T)]
[969b3fe]89
[8c50aed]90static inline uint32_t __tls_rand() {
[21184e3]91 kernelTLS.rand_seed ^= kernelTLS.rand_seed << 6;
92 kernelTLS.rand_seed ^= kernelTLS.rand_seed >> 21;
93 kernelTLS.rand_seed ^= kernelTLS.rand_seed << 7;
94 return kernelTLS.rand_seed;
95}
96
[de94a60]97
[a1a17a74]98void doregister( struct cluster & cltr );
99void unregister( struct cluster & cltr );
[de94a60]100
[ac2b598]101void doregister( struct cluster * cltr, struct $thread & thrd );
102void unregister( struct cluster * cltr, struct $thread & thrd );
[de94a60]103
[504a7dc]104void doregister( struct cluster * cltr, struct processor * proc );
105void unregister( struct cluster * cltr, struct processor * proc );
106
[7768b8d]107//=======================================================================
108// Cluster lock API
109//=======================================================================
[b388ee81]110// Cells use by the reader writer lock
111// while not generic it only relies on a opaque pointer
[9b1dcc2]112struct __attribute__((aligned(64))) __scheduler_lock_id_t {
113 __processor_id_t * volatile handle;
[7768b8d]114 volatile bool lock;
115};
116
117// Lock-Free registering/unregistering of threads
118// Register a processor to a given cluster and get its unique id in return
[9b1dcc2]119unsigned doregister( struct __processor_id_t * proc );
[7768b8d]120
121// Unregister a processor from a given cluster using its id, getting back the original pointer
[9b1dcc2]122void unregister( struct __processor_id_t * proc );
[7768b8d]123
124//=======================================================================
125// Reader-writer lock implementation
126// Concurrent with doregister/unregister,
127// i.e., threads can be added at any point during or between the entry/exit
[dca5802]128
129//-----------------------------------------------------------------------
130// simple spinlock underlying the RWLock
131// Blocking acquire
[7768b8d]132static inline void __atomic_acquire(volatile bool * ll) {
133 while( __builtin_expect(__atomic_exchange_n(ll, (bool)true, __ATOMIC_SEQ_CST), false) ) {
134 while(__atomic_load_n(ll, (int)__ATOMIC_RELAXED))
135 asm volatile("pause");
136 }
137 /* paranoid */ verify(*ll);
138}
139
[dca5802]140// Non-Blocking acquire
[7768b8d]141static inline bool __atomic_try_acquire(volatile bool * ll) {
[b798713]142 return !__atomic_exchange_n(ll, (bool)true, __ATOMIC_SEQ_CST);
[7768b8d]143}
144
[dca5802]145// Release
[7768b8d]146static inline void __atomic_unlock(volatile bool * ll) {
147 /* paranoid */ verify(*ll);
148 __atomic_store_n(ll, (bool)false, __ATOMIC_RELEASE);
149}
150
[b388ee81]151//-----------------------------------------------------------------------
152// Reader-Writer lock protecting the ready-queues
153// while this lock is mostly generic some aspects
154// have been hard-coded to for the ready-queue for
155// simplicity and performance
156struct __scheduler_RWLock_t {
157 // total cachelines allocated
158 unsigned int max;
159
160 // cachelines currently in use
161 volatile unsigned int alloc;
162
163 // cachelines ready to itereate over
164 // (!= to alloc when thread is in second half of doregister)
165 volatile unsigned int ready;
166
167 // writer lock
168 volatile bool lock;
169
170 // data pointer
[9b1dcc2]171 __scheduler_lock_id_t * data;
[b388ee81]172};
173
174void ?{}(__scheduler_RWLock_t & this);
175void ^?{}(__scheduler_RWLock_t & this);
176
177extern __scheduler_RWLock_t * __scheduler_lock;
178
[7768b8d]179//-----------------------------------------------------------------------
180// Reader side : acquire when using the ready queue to schedule but not
181// creating/destroying queues
[9b1dcc2]182static inline void ready_schedule_lock( struct __processor_id_t * proc) with(*__scheduler_lock) {
[7768b8d]183 unsigned iproc = proc->id;
184 /*paranoid*/ verify(data[iproc].handle == proc);
185 /*paranoid*/ verify(iproc < ready);
186
187 // Step 1 : make sure no writer are in the middle of the critical section
188 while(__atomic_load_n(&lock, (int)__ATOMIC_RELAXED))
189 asm volatile("pause");
190
191 // Fence needed because we don't want to start trying to acquire the lock
192 // before we read a false.
193 // Not needed on x86
194 // std::atomic_thread_fence(std::memory_order_seq_cst);
195
196 // Step 2 : acquire our local lock
197 __atomic_acquire( &data[iproc].lock );
198 /*paranoid*/ verify(data[iproc].lock);
199}
200
[9b1dcc2]201static inline void ready_schedule_unlock( struct __processor_id_t * proc) with(*__scheduler_lock) {
[7768b8d]202 unsigned iproc = proc->id;
203 /*paranoid*/ verify(data[iproc].handle == proc);
204 /*paranoid*/ verify(iproc < ready);
205 /*paranoid*/ verify(data[iproc].lock);
[dca5802]206 __atomic_unlock(&data[iproc].lock);
[7768b8d]207}
208
209//-----------------------------------------------------------------------
210// Writer side : acquire when changing the ready queue, e.g. adding more
211// queues or removing them.
[b388ee81]212uint_fast32_t ready_mutate_lock( void );
[7768b8d]213
[b388ee81]214void ready_mutate_unlock( uint_fast32_t /* value returned by lock */ );
[7768b8d]215
[b798713]216//=======================================================================
217// Ready-Queue API
[dca5802]218//-----------------------------------------------------------------------
219// push thread onto a ready queue for a cluster
220// returns true if the list was previously empty, false otherwise
[504a7dc]221__attribute__((hot)) bool push(struct cluster * cltr, struct $thread * thrd);
[dca5802]222
223//-----------------------------------------------------------------------
224// pop thread from the ready queue of a cluster
225// returns 0p if empty
[504a7dc]226__attribute__((hot)) struct $thread * pop(struct cluster * cltr);
[dca5802]227
228//-----------------------------------------------------------------------
229// Increase the width of the ready queue (number of lanes) by 4
[b798713]230void ready_queue_grow (struct cluster * cltr);
[dca5802]231
232//-----------------------------------------------------------------------
233// Decrease the width of the ready queue (number of lanes) by 4
[b798713]234void ready_queue_shrink(struct cluster * cltr);
235
[dca5802]236//-----------------------------------------------------------------------
237// Statics call at the end of each thread to register statistics
[b798713]238#if !defined(__CFA_NO_STATISTICS__)
239void stats_tls_tally(struct cluster * cltr);
240#else
241static inline void stats_tls_tally(struct cluster * cltr) {}
242#endif
[de94a60]243
[75f3522]244// Local Variables: //
245// mode: c //
246// tab-width: 4 //
[4aa2fb2]247// End: //
Note: See TracBrowser for help on using the repository browser.