source: libcfa/src/concurrency/kernel.hfa @ 8834751

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

Moved statistics to stats.cfa to combine ready Q stats and IO stats

  • Property mode set to 100644
File size: 6.6 KB
Line 
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//
7// kernel --
8//
9// Author           : Thierry Delisle
10// Created On       : Tue Jan 17 12:27:26 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Feb  4 12:29:26 2020
13// Update Count     : 22
14//
15
16#pragma once
17
18#include <stdbool.h>
19#include <stdint.h>
20
21#include "invoke.h"
22#include "time_t.hfa"
23#include "coroutine.hfa"
24
25extern "C" {
26#include <pthread.h>
27#include <semaphore.h>
28}
29
30//-----------------------------------------------------------------------------
31// Locks
32struct semaphore {
33        __spinlock_t lock;
34        int count;
35        __queue_t($thread) waiting;
36};
37
38void  ?{}(semaphore & this, int count = 1);
39void ^?{}(semaphore & this);
40bool   P (semaphore & this);
41bool   V (semaphore & this);
42bool   V (semaphore & this, unsigned count);
43
44
45//-----------------------------------------------------------------------------
46// Processor
47extern struct cluster * mainCluster;
48
49// Processor id, required for scheduling threads
50struct __processor_id_t {
51        unsigned id;
52
53        #if !defined(__CFA_NO_STATISTICS__)
54                struct __stats_t * stats;
55        #endif
56};
57
58coroutine processorCtx_t {
59        struct processor * proc;
60};
61
62// Wrapper around kernel threads
63struct processor {
64        inline __processor_id_t;
65
66        // Main state
67        // Coroutine ctx who does keeps the state of the processor
68        struct processorCtx_t runner;
69
70        // Cluster from which to get threads
71        struct cluster * cltr;
72
73        // Name of the processor
74        const char * name;
75
76        // Handle to pthreads
77        pthread_t kernel_thread;
78
79        // RunThread data
80        // Action to do after a thread is ran
81        $thread * destroyer;
82
83        // Preemption data
84        // Node which is added in the discrete event simulaiton
85        struct alarm_node_t * preemption_alarm;
86
87        // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
88        bool pending_preemption;
89
90        // Idle lock (kernel semaphore)
91        __bin_sem_t idle;
92
93        // Termination
94        // Set to true to notify the processor should terminate
95        volatile bool do_terminate;
96
97        // Termination synchronisation (user semaphore)
98        semaphore terminated;
99
100        // pthread Stack
101        void * stack;
102
103        // Link lists fields
104        struct __dbg_node_cltr {
105                processor * next;
106                processor * prev;
107        } node;
108
109#ifdef __CFA_DEBUG__
110        // Last function to enable preemption on this processor
111        const char * last_enable;
112#endif
113};
114
115void  ?{}(processor & this, const char name[], struct cluster & cltr);
116void ^?{}(processor & this);
117
118static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
119static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
120static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
121
122static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; }
123
124//-----------------------------------------------------------------------------
125// I/O
126struct __io_data;
127
128#define CFA_CLUSTER_IO_POLLER_USER_THREAD    1 << 0 // 0x1
129#define CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS 1 << 1 // 0x2
130// #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 2 // 0x4
131#define CFA_CLUSTER_IO_BUFFLEN_OFFSET        16
132
133
134//-----------------------------------------------------------------------------
135// Cluster Tools
136
137// Intrusives lanes which are used by the relaxed ready queue
138struct __attribute__((aligned(128))) __intrusive_lane_t;
139void  ?{}(__intrusive_lane_t & this);
140void ^?{}(__intrusive_lane_t & this);
141
142// Counter used for wether or not the lanes are all empty
143struct __attribute__((aligned(128))) __snzi_node_t;
144struct __snzi_t {
145        unsigned mask;
146        int root;
147        __snzi_node_t * nodes;
148};
149
150void  ?{}( __snzi_t & this, unsigned depth );
151void ^?{}( __snzi_t & this );
152
153//TODO adjust cache size to ARCHITECTURE
154// Structure holding the relaxed ready queue
155struct __attribute__((aligned(128))) __ready_queue_t {
156        // Data tracking how many/which lanes are used
157        // Aligned to 128 for cache locality
158        __snzi_t snzi;
159
160        // Data tracking the actual lanes
161        // On a seperate cacheline from the used struct since
162        // used can change on each push/pop but this data
163        // only changes on shrink/grow
164        struct __attribute__((aligned(64))) {
165                // Arary of lanes
166                __intrusive_lane_t * volatile data;
167
168                // Number of lanes (empty or not)
169                volatile size_t count;
170        } lanes;
171};
172
173void  ?{}(__ready_queue_t & this);
174void ^?{}(__ready_queue_t & this);
175
176//-----------------------------------------------------------------------------
177// Cluster
178struct cluster {
179        // Ready queue for threads
180        __ready_queue_t ready_queue;
181
182        // Name of the cluster
183        const char * name;
184
185        // Preemption rate on this cluster
186        Duration preemption_rate;
187
188        // List of processors
189        __spinlock_t idle_lock;
190        __dllist_t(struct processor) procs;
191        __dllist_t(struct processor) idles;
192        unsigned int nprocessors;
193
194        // List of threads
195        __spinlock_t thread_list_lock;
196        __dllist_t(struct $thread) threads;
197        unsigned int nthreads;
198
199        // Link lists fields
200        struct __dbg_node_cltr {
201                cluster * next;
202                cluster * prev;
203        } node;
204
205        struct __io_data * io;
206
207        #if !defined(__CFA_NO_STATISTICS__)
208                bool print_stats;
209                struct __stats_t * stats;
210        #endif
211};
212extern Duration default_preemption();
213
214void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned flags);
215void ^?{}(cluster & this);
216
217static inline void ?{} (cluster & this)                                           { this{"Anonymous Cluster", default_preemption(), 0}; }
218static inline void ?{} (cluster & this, Duration preemption_rate)                 { this{"Anonymous Cluster", preemption_rate, 0}; }
219static inline void ?{} (cluster & this, const char name[])                        { this{name, default_preemption(), 0}; }
220static inline void ?{} (cluster & this, unsigned flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
221static inline void ?{} (cluster & this, Duration preemption_rate, unsigned flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
222static inline void ?{} (cluster & this, const char name[], unsigned flags)        { this{name, default_preemption(), flags}; }
223
224static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
225
226static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
227static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
228
229#if !defined(__CFA_NO_STATISTICS__)
230        static inline void print_stats_at_exit( cluster & this ) {
231                this.print_stats = true;
232        }
233#endif
234
235// Local Variables: //
236// mode: c //
237// tab-width: 4 //
238// End: //
Note: See TracBrowser for help on using the repository browser.