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