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