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