41
|
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
|