Mercurial > hg > CbC > CbC_xv6
comparison src/context.h @ 41:087d7b61c86b
cbc cmake version
author | kono |
---|---|
date | Sat, 02 Mar 2019 19:01:03 +0900 |
parents | |
children | 233a68a261fe |
comparison
equal
deleted
inserted
replaced
40:162d92edbb0a | 41:087d7b61c86b |
---|---|
1 /* Context definition for llrb example */ | |
2 #ifndef CONTEXT_H | |
3 #define CONTEXT_H | |
4 #include <stdlib.h> | |
5 #include <pthread.h> | |
6 #ifdef USE_CUDAWorker | |
7 #include <cuda.h> | |
8 #include <driver_types.h> | |
9 #include <cuda_runtime.h> | |
10 #include "helper_cuda.h" | |
11 #endif | |
12 | |
13 #define ALLOCATE_SIZE 20000000 | |
14 #define NEW(type) (type*)(calloc(1, sizeof(type))) | |
15 #define NEWN(n, type) (type*)(calloc(n, sizeof(type))) | |
16 | |
17 #define ALLOC_DATA(context, dseg) ({\ | |
18 Meta* meta = (Meta*)context->heap;\ | |
19 meta->type = D_##dseg;\ | |
20 meta->size = sizeof(dseg);\ | |
21 meta->len = 1;\ | |
22 context->heap += sizeof(Meta);\ | |
23 context->data[D_##dseg] = context->heap; context->heap += sizeof(dseg); (dseg *)context->data[D_##dseg]; }) | |
24 | |
25 #define ALLOC_DATA_TYPE(context, dseg, t) ({\ | |
26 Meta* meta = (Meta*)context->heap;\ | |
27 meta->type = D_##t;\ | |
28 meta->size = sizeof(t);\ | |
29 meta->len = 1;\ | |
30 context->heap += sizeof(Meta);\ | |
31 context->data[D_##dseg] = context->heap; context->heap += sizeof(t); (t *)context->data[D_##dseg]; }) | |
32 | |
33 #define ALLOCATE(context, t) ({ \ | |
34 Meta* meta = (Meta*)context->heap;\ | |
35 context->heap += sizeof(Meta);\ | |
36 union Data* data = context->heap; \ | |
37 context->heap += sizeof(t); \ | |
38 meta->type = D_##t; \ | |
39 meta->size = sizeof(t); \ | |
40 meta->len = 1;\ | |
41 data; }) | |
42 | |
43 #define ALLOCATE_ARRAY(context, t, length) ({ \ | |
44 Meta* meta = (Meta*)context->heap;\ | |
45 context->heap += sizeof(Meta);\ | |
46 union Data* data = context->heap; \ | |
47 context->heap += sizeof(t)*length; \ | |
48 meta->type = D_##t; \ | |
49 meta->size = sizeof(t)*length; \ | |
50 meta->len = length; \ | |
51 data; }) | |
52 | |
53 #define ALLOCATE_PTR_ARRAY(context, dseg, length) ({\ | |
54 Meta* meta = (Meta*)context->heap;\ | |
55 context->heap += sizeof(Meta);\ | |
56 union Data* data = context->heap; \ | |
57 context->heap += sizeof(dseg *)*length; \ | |
58 meta->type = D_##dseg; \ | |
59 meta->size = sizeof(dseg *)*length; \ | |
60 meta->len = length; \ | |
61 data; }) | |
62 | |
63 #define ALLOCATE_DATA_GEAR(context, t) ({ \ | |
64 union Data* data = ALLOCATE(context, t); \ | |
65 Meta* meta = GET_META(data); \ | |
66 meta->wait = createSynchronizedQueue(context); \ | |
67 data; }) | |
68 | |
69 #define ALLOC(context, t) (&ALLOCATE(context, t)->t) | |
70 | |
71 #define GET_META(dseg) ((Meta*)(((void*)dseg) - sizeof(Meta))) | |
72 #define GET_TYPE(dseg) (GET_META(dseg)->type) | |
73 #define GET_SIZE(dseg) (GET_META(dseg)->size) | |
74 #define GET_LEN(dseg) (GET_META(dseg)->len) | |
75 #define GET_WAIT_LIST(dseg) (GET_META(dseg)->wait) | |
76 | |
77 #define Gearef(context, t) (&(context)->data[D_##t]->t) | |
78 | |
79 // (SingleLinkedStack *)context->data[D_Stack]->Stack.stack->Stack.stack | |
80 | |
81 #define GearImpl(context, intf, name) (Gearef(context, intf)->name->intf.name) | |
82 | |
83 #include "c/enumCode.h" | |
84 | |
85 enum Relational { | |
86 EQ, | |
87 GT, | |
88 LT, | |
89 }; | |
90 | |
91 #include "c/enumData.h" | |
92 | |
93 struct Context { | |
94 enum Code next; | |
95 struct Worker* worker; | |
96 struct TaskManager* taskManager; | |
97 int codeNum; | |
98 __code (**code) (struct Context*); | |
99 union Data **data; | |
100 void* heapStart; | |
101 void* heap; | |
102 long heapLimit; | |
103 int dataNum; | |
104 | |
105 // task parameter | |
106 int idgCount; //number of waiting dataGear | |
107 int idg; | |
108 int maxIdg; | |
109 int odg; | |
110 int maxOdg; | |
111 int gpu; // GPU task | |
112 struct Context* task; | |
113 struct Element* taskList; | |
114 #ifdef USE_CUDAWorker | |
115 int num_exec; | |
116 CUmodule module; | |
117 CUfunction function; | |
118 #endif | |
119 /* multi dimension parameter */ | |
120 int iterate; | |
121 struct Iterator* iterator; | |
122 enum Code before; | |
123 }; | |
124 | |
125 typedef int Int; | |
126 #ifndef USE_CUDAWorker | |
127 typedef unsigned long long CUdeviceptr; | |
128 #endif | |
129 union Data { | |
130 struct Meta { | |
131 enum DataType type; | |
132 long size; | |
133 long len; | |
134 struct Queue* wait; // tasks waiting this dataGear | |
135 } Meta; | |
136 struct Context Context; | |
137 struct Timer { | |
138 union Data* timer; | |
139 enum Code start; | |
140 enum Code end; | |
141 enum Code next; | |
142 } Timer; | |
143 struct TimerImpl { | |
144 double time; | |
145 } TimerImpl; | |
146 struct LoopCounter { | |
147 int i; | |
148 } LoopCounter; | |
149 struct TaskManager { | |
150 union Data* taskManager; | |
151 enum Code spawn; // start NEW context on the worker | |
152 enum Code spawnTasks; // start NEW tasks on the worker | |
153 enum Code shutdown; | |
154 enum Code incrementTaskCount; | |
155 enum Code decrementTaskCount; | |
156 enum Code next; | |
157 enum Code next1; | |
158 enum Code setWaitTask; | |
159 struct Context* task; | |
160 struct Element* taskList; | |
161 union Data* data; | |
162 } TaskManager; | |
163 struct TaskManagerImpl { | |
164 enum Code next; | |
165 int numWorker; | |
166 int sendCPUWorkerIndex; | |
167 int sendGPUWorkerIndex; | |
168 int taskCount; | |
169 pthread_mutex_t mutex; | |
170 struct Queue* activeQueue; | |
171 struct Worker** workers; | |
172 struct Element* taskList; | |
173 int loopCounter; | |
174 int cpu; | |
175 int gpu; | |
176 int io; | |
177 int maxCPU; | |
178 } TaskManagerImpl; | |
179 struct Worker { | |
180 union Data* worker; | |
181 enum Code taskReceive; | |
182 enum Code shutdown; | |
183 enum Code next; | |
184 struct Queue* tasks; | |
185 pthread_t thread; | |
186 struct TaskManager* taskManager; | |
187 struct Context* task; | |
188 } Worker; | |
189 struct CPUWorker { | |
190 pthread_mutex_t mutex; | |
191 pthread_cond_t cond; | |
192 struct Context* context; | |
193 int id; | |
194 int loopCounter; | |
195 } CPUWorker; | |
196 #ifdef USE_CUDAWorker | |
197 struct CUDAWorker { | |
198 CUdevice device; | |
199 CUcontext cuCtx; | |
200 struct Context* context; | |
201 int id; | |
202 int loopCounter; | |
203 int deviceNum; | |
204 struct Queue* tasks; | |
205 int runFlag; | |
206 enum Code next; | |
207 int numStream; | |
208 struct Executor* executor; | |
209 CUstream *stream; | |
210 } CUDAWorker; | |
211 #else | |
212 struct CUDAWorker { | |
213 } CUDAWorker; | |
214 #endif | |
215 struct Main { | |
216 enum Code code; | |
217 enum Code next; | |
218 struct Queue* args; | |
219 } Main; | |
220 // Queue Interface | |
221 struct Queue { | |
222 union Data* queue; | |
223 union Data* data; | |
224 enum Code whenEmpty; | |
225 enum Code clear; | |
226 enum Code put; | |
227 enum Code take; | |
228 enum Code isEmpty; | |
229 enum Code next; | |
230 } Queue; | |
231 struct SingleLinkedQueue { | |
232 struct Element* top; | |
233 struct Element* last; | |
234 } SingleLinkedQueue; | |
235 struct SynchronizedQueue { | |
236 struct Element* top; | |
237 struct Element* last; | |
238 struct Atomic* atomic; | |
239 } SynchronizedQueue; | |
240 // Stack Interface | |
241 struct Stack { | |
242 union Data* stack; | |
243 union Data* data; | |
244 union Data* data1; | |
245 enum Code whenEmpty; | |
246 enum Code clear; | |
247 enum Code push; | |
248 enum Code pop; | |
249 enum Code pop2; | |
250 enum Code isEmpty; | |
251 enum Code get; | |
252 enum Code get2; | |
253 enum Code next; | |
254 } Stack; | |
255 // Stack implementations | |
256 struct SingleLinkedStack { | |
257 struct Element* top; | |
258 } SingleLinkedStack; | |
259 struct ArrayStack { | |
260 int size; | |
261 int limit; | |
262 struct Element* array; | |
263 } ArrayStack; | |
264 // Stack implementation end | |
265 struct Element { | |
266 union Data* data; | |
267 struct Element* next; | |
268 } Element; | |
269 struct Array { | |
270 int prefix; | |
271 Int* array; | |
272 } Array; | |
273 struct Tree { | |
274 union Data* tree; | |
275 struct Node* node; | |
276 enum Code put; | |
277 enum Code get; | |
278 enum Code remove; | |
279 enum Code clear; | |
280 enum Code next; | |
281 } Tree; | |
282 struct RedBlackTree { | |
283 struct Node* root; | |
284 struct Node* current; // reading node of original tree | |
285 struct Node* previous; // parent of reading node of original tree | |
286 struct Node* newNode; // writing node of new tree | |
287 struct Node* parent; | |
288 struct Node* grandparent; | |
289 struct Stack* nodeStack; | |
290 enum Code findNodeNext; | |
291 int result; | |
292 } RedBlackTree; | |
293 struct RotateTree { | |
294 enum Code next; | |
295 struct RedBlackTree* traverse; | |
296 struct Tree* tree; | |
297 } RotateTree; | |
298 struct Node { | |
299 int key; // comparable data segment | |
300 union Data* value; | |
301 struct Node* left; | |
302 struct Node* right; | |
303 // need to balancing | |
304 enum Color { | |
305 Red, | |
306 Black, | |
307 // Red eq 0,Black eq 1. enum name convert intager. | |
308 } color; | |
309 } Node; | |
310 struct Atomic { | |
311 union Data* atomic; | |
312 union Data** ptr; | |
313 union Data* oldData; | |
314 union Data* newData; | |
315 enum Code checkAndSet; | |
316 enum Code next; | |
317 enum Code fail; | |
318 } Atomic; | |
319 struct AtomicReference { | |
320 } AtomicReference; | |
321 struct Semaphore { | |
322 union Data* semaphore; | |
323 enum Code p; | |
324 enum Code v; | |
325 enum Code next; | |
326 } Semaphore; | |
327 struct SemaphoreImpl { | |
328 int value; | |
329 struct Lock* lock; | |
330 struct Queue* waitThreadQueue; | |
331 } SemaphoreImpl; | |
332 struct Allocate { | |
333 enum Code next; | |
334 long size; | |
335 } Allocate; | |
336 struct Integer { | |
337 int value; | |
338 } Integer; | |
339 struct SortArray { | |
340 struct Integer *array; //Array arrayじゃできない? | |
341 int loopCounter; | |
342 int block; | |
343 int first; | |
344 int prefix; | |
345 } SortArray; | |
346 struct Iterator { | |
347 union Data* iterator; | |
348 struct Context* task; | |
349 int numGPU; | |
350 enum Code exec; | |
351 enum Code barrier; | |
352 enum Code whenWait; | |
353 enum Code next; | |
354 } Iterator; | |
355 struct MultiDimIterator { | |
356 int x; | |
357 int y; | |
358 int z; | |
359 int count; | |
360 int counterX; | |
361 int counterY; | |
362 int counterZ; | |
363 } MultiDimIterator; | |
364 struct MultiDim { | |
365 int x; | |
366 int y; | |
367 int z; | |
368 } MultiDim; | |
369 struct Executor { | |
370 union Data* executor; | |
371 struct Context* task; | |
372 enum Code read; | |
373 enum Code exec; | |
374 enum Code write; | |
375 enum Code next; | |
376 } Executor; | |
377 #ifdef USE_CUDAWorker | |
378 struct CUDAExecutor { | |
379 CUdeviceptr** kernelParams; | |
380 struct CUDABuffer* buffer; | |
381 int maxThreadPerBlock; | |
382 int maxThreadPerBlockX; | |
383 int maxThreadPerBlockY; | |
384 int maxThreadPerBlockZ; | |
385 struct Timer* timer; | |
386 } CUDAExecutor; | |
387 struct CUDABuffer { | |
388 int inputLen; | |
389 int outputLen; | |
390 union Data** inputData; | |
391 union Data** outputData; | |
392 } CUDABuffer; | |
393 CUdeviceptr CUdeviceptr; | |
394 #else | |
395 struct CUDAExecutor { | |
396 } CUDAExecutor; | |
397 struct CUDABuffer { | |
398 } CUDABuffer; | |
399 CUdeviceptr CUdeviceptr; | |
400 #endif | |
401 Int Int; | |
402 struct Memory { | |
403 union Data* adr; | |
404 int length; | |
405 union Data* body; | |
406 int hash; | |
407 } Memory; | |
408 struct Buffer { | |
409 union Data* buffer; | |
410 union Data* data; | |
411 enum Code put; | |
412 enum Code take; | |
413 enum Code next; | |
414 } Buffer; | |
415 struct BoundedBuffer { | |
416 struct Element* top; | |
417 struct Element* last; | |
418 struct Semaphore* fullCount; | |
419 struct Semaphore* emptyCount; | |
420 struct Semaphore* lock; | |
421 } BoundedBuffer; | |
422 struct Lock { | |
423 union Data* lock; | |
424 enum Code doLock; | |
425 enum Code doUnlock; | |
426 enum Code next; | |
427 } Lock; | |
428 struct LockImpl { | |
429 Int* lock; | |
430 struct Queue* waitThreadQueue; | |
431 struct Atomic* atomic; | |
432 struct Context* lockContext; | |
433 } LockImpl; | |
434 struct SpinLock { | |
435 volatile Int* lock; | |
436 struct Atomic* atomic; | |
437 struct Context* lockContext; | |
438 } SpinLock; | |
439 }; // union Data end this is necessary for context generator | |
440 typedef union Data Data; | |
441 | |
442 #include "c/typedefData.h" | |
443 | |
444 #include "c/extern.h" | |
445 | |
446 extern __code start_code(struct Context* context); | |
447 extern __code exit_code(struct Context* context); | |
448 extern __code meta(struct Context* context, enum Code next); | |
449 //extern __code par_meta(struct Context* context, enum Code spawns, enum Code next); | |
450 extern __code parGotoMeta(struct Context* context, enum Code next); | |
451 extern void initContext(struct Context* context); | |
452 | |
453 #endif |