# HG changeset patch # User Takato Matsuoka # Date 1642503268 -32400 # Node ID e6778c866876c341332d9ec4e77db65e66e0c71a # Parent a9c630cc1c6540dceb01e2d31dac0c41b2dcbfcb add DebugWorker and DebugTaskManager diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/CMakeLists.txt --- a/src/parallel_execution/CMakeLists.txt Sat Jan 15 17:43:04 2022 +0900 +++ b/src/parallel_execution/CMakeLists.txt Tue Jan 18 19:54:28 2022 +0900 @@ -180,6 +180,14 @@ TaskManagerImpl.cbc CPUWorker.cbc SynchronizedQueue.cbc AtomicReference.cbc SingleLinkedStack.cbc examples/helloWorld/main.cbc examples/helloWorld/HelloImpl.cbc ) +GearsCommand( + TARGET + Debug_hello_world + SOURCES + CPUWorker.cbc SynchronizedQueue.cbc AtomicReference.cbc SingleLinkedStack.cbc examples/DebughelloWorld/main.cbc examples/DebughelloWorld/HelloImpl.cbc + DebugWorker/DebugWorker.cbc DebugTaskManagerImpl.cbc DebugWorker/crc32.c DebugWorker/memory.c DebugWorker/state_db.c +) + GearsCommand( TARGET @@ -212,6 +220,14 @@ TaskManagerImpl.cbc CPUWorker.cbc SingleLinkedQueue.cbc AtomicReference.cbc SynchronizedQueue.cbc examples/gearsFile/GearsFileImpl.cbc examples/gearsFile/GearsFile_test.cbc ) +GearsCommand( + TARGET + Debug_gearsFile + SOURCES + CPUWorker.cbc SingleLinkedQueue.cbc AtomicReference.cbc SynchronizedQueue.cbc examples/gearsFile/GearsFileImpl.cbc examples/gearsFile/GearsFile_test.cbc + DebugWorker/DebugWorker.cbc DebugTaskManagerImpl.cbc +) + GearsCommand( TARGET @@ -270,4 +286,4 @@ socket_wc SOURCES examples/socketQueue/RemoteDGMQueue.cbc examples/socketQueue/wordCount_Remote.cbc AtomicReference.cbc SingleLinkedStack.cbc -) \ No newline at end of file +) diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugTaskManagerImpl.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugTaskManagerImpl.cbc Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,240 @@ +#include "../context.h" +#interface "TaskManager.h" +#interface "Iterator.h" +#interface "Queue.h" +#interface "Worker.h" + +#include +#include + +// プロトタイプ宣言 +static void defaultStatefunc(DebugTaskManagerImpl* debugTaskManagerImpl, struct DebugWorker* debugWorker , StateDB now,StateDB next,int flag) { +} +void createWorkers(struct Context* context, DebugTaskManagerImpl* taskManager); + +// DebugTaskManagerの作成。enumや変数の初期化を行う。 +TaskManager* createDebugTaskManagerImpl(struct Context* context, int numCPU, int numGPU, int numIO) { + printf("[Debug log] createDebugTaskManagerImpl in DebugTaskManager\n"); + // TaskManager構造体の生成および、構造体で定義された関数とenumの紐付け。 + struct TaskManager* taskManager = new TaskManager(); + taskManager->spawnTasks = C_spawnTasksDebugTaskManagerImpl; + taskManager->spawn = C_spawnDebugTaskManagerImpl; + taskManager->shutdown = C_shutdownDebugTaskManagerImpl; + taskManager->incrementTaskCount = C_incrementTaskCountDebugTaskManagerImpl; + taskManager->decrementTaskCount = C_decrementTaskCountDebugTaskManagerImpl; + taskManager->setWaitTask = C_setWaitTaskDebugTaskManagerImpl; + + // Impl構造体の生成および、構造体で定義された変数の初期化 + struct DebugTaskManagerImpl* taskManagerImpl = new DebugTaskManagerImpl(); + // 0...numIO-1 IOProcessor + // numIO...numIO+numGPU-1 GPUProcessor + // numIO+numGPU...numIO+numGPU+numCPU-1 CPUProcessor + taskManagerImpl->io = 0; + taskManagerImpl->gpu = numIO; + taskManagerImpl->cpu = numIO+numGPU; + taskManagerImpl->maxCPU = numIO+numGPU+numCPU; + taskManagerImpl->numWorker = taskManagerImpl->maxCPU; + taskManagerImpl->sendGPUWorkerIndex = taskManagerImpl->gpu; + taskManagerImpl->sendCPUWorkerIndex = taskManagerImpl->cpu; + taskManagerImpl->taskCount = 0; + taskManagerImpl->loopCounter = 0; + taskManagerImpl->mem = 0; + taskManagerImpl->statefunc = defaultStatefunc; + context->taskManager = taskManager; + createWorkers(context, taskManagerImpl); + taskManager->taskManager = (union Data*)taskManagerImpl; + return taskManager; +} + +// workerの作成。CPUやGPU, モデル検査など環境によって作成するWorkerを変更する。 +void createWorkers(struct Context* context, DebugTaskManagerImpl* taskManager) { + printf("[Debug log] createWorkers in DebugTaskManager\n"); + int i = 0; + taskManager->workers = (Worker**)ALLOCATE_PTR_ARRAY(context, Worker, taskManager->maxCPU); + for (;igpu;i++) { + Queue* queue = createSynchronizedQueue(context); + taskManager->workers[i] = (Worker*)createCPUWorker(context, i, queue); + } + for (;icpu;i++) { + Queue* queue = createSynchronizedQueue(context); +#ifdef USE_CUDAWorker + taskManager->workers[i] = (Worker*)createCUDAWorker(context, i, queue,0); +#else + taskManager->workers[i] = (Worker*)createDebugWorker(context, i, queue); +#endif + } + for (;imaxCPU;i++) { + Queue* queue = createSynchronizedQueue(context); + taskManager->workers[i] = (Worker*)createDebugWorker(context, i, queue); + } +} + +// 一連のspawnTaskの始動関数 +__code spawnTasksDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManager, struct Element* taskList, __code next1(...)) { + printf("[Debug log] spawnTaskDebugTaskManagerImpl in DebugTaskManager\n"); + taskManager->taskList = taskList; + goto spawnTasksDebugTaskManagerImpl1(); +} + +__code spawnTasksDebugTaskManagerImpl1(struct DebugTaskManagerImpl* taskManagerImpl, struct TaskManager* taskManager) { + printf("[Debug log] spawnTasksDebugTaskManagerImpl1 in DebugTaskManager\n"); + // TaskListにTaskがない場合 + if (taskManagerImpl->taskList == NULL) { + goto spawnTasksDebugTaskManagerImpl2(); + } + // TaskListにTaskがあった場合、taskListからtaskを取り出し、taskListを次のtaskへ更新してsetWaitTaskへ継続。 + struct Context* task = (struct Context*)taskManagerImpl->taskList->data; + taskManagerImpl->taskList = taskManagerImpl->taskList->next; + goto taskManager->setWaitTask(task, spawnTasksDebugTaskManagerImpl1); +} + +__code spawnTasksDebugTaskManagerImpl1_stub(struct Context* context) { + DebugTaskManagerImpl* taskManagerImpl = (DebugTaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + TaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnTasksDebugTaskManagerImpl1(context, taskManagerImpl, taskManager); +} + +__code spawnTasksDebugTaskManagerImpl2(struct DebugTaskManagerImpl* taskManager, struct Element* taskList, __code next1(...)) { + printf("[Debug log] spawnTasksDebugTaskManagerImpl2 DebugTaskManager\n"); + taskManager->taskList = taskList; + goto spawnTasksDebugTaskManagerImpl3(); +} + +__code spawnTasksDebugTaskManagerImpl3(struct DebugTaskManagerImpl* taskManagerImpl, __code next1(...), struct TaskManager* taskManager) { + printf("[Debug log] spawnTasksDebugTaskManagerImpl3 in DebugTaskManager\n"); + if (taskManagerImpl->taskList == NULL) { + // struct Queue* tasks = taskManagerImpl->workers[0]->tasks; + // printf("put NULL\n"); + printf("execute spawnDebugTaskManagerImpl3\n"); + goto next1(...); + } + struct Context* task = (struct Context*)taskManagerImpl->taskList->data; + taskManagerImpl->taskList = taskManagerImpl->taskList->next; + goto taskManager->spawn(task, spawnTasksDebugTaskManagerImpl3); +} + +__code spawnTasksDebugTaskManagerImpl3_stub(struct Context* context) { + DebugTaskManagerImpl* taskManagerImpl = (DebugTaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + enum Code next1 = Gearef(context, TaskManager)->next1; + TaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnTasksDebugTaskManagerImpl3(context, taskManagerImpl, next1, taskManager); +} + +// TaskをQueueにputする +__code setWaitTaskDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + printf("[Debug log] setWaitTaskDebugTaskManagerImpl in DebugTaskManager\n"); + int i = taskManager->loopCounter; + if (task->idg+i < task->maxIdg) { + struct Queue* queue = GET_WAIT_LIST(task->data[task->idg + i]); + taskManager->loopCounter++; + goto queue->put(task, setWaitTaskDebugTaskManagerImpl); + } + taskManager->loopCounter = 0; + goto incrementTaskCountDebugTaskManagerImpl(); +} + +__code incrementTaskCountDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManager, __code next(...)) { + printf("[Debug log] incrementTaskCountDebugTaskManagerImpl in DebugTaskManager\n"); + __sync_fetch_and_add(&taskManager->taskCount, 1); + goto next(...); +} + +__code decrementTaskCountDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManager, __code next(...)) { + printf("[Debug log] decrementTaskCountDebugTaskManagerImpl in DebugTaskManager\n"); + __sync_fetch_and_sub(&taskManager->taskCount, 1); + goto next(...); +} + +__code spawnDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManagerImpl, struct Context* task, __code next(...), struct TaskManager* taskManager) { + printf("[Debug log] spawnDebugTaskManagerImpl in DebugTaskManager\n"); + task->taskManager = taskManager; + if (task->idgCount == 0) { + // iterator task is normal task until spawned + if (task->iterator != NULL && task->iterate == 0) { + pthread_mutex_unlock(&taskManagerImpl->mutex); + struct Iterator* iterator = task->iterator; + goto iterator->exec(task, taskManagerImpl->cpu - taskManagerImpl->gpu, next(...)); + } + goto taskSend(); + } + pthread_mutex_unlock(&taskManagerImpl->mutex); + goto next(...); +} + +__code spawnDebugTaskManagerImpl_stub(struct Context* context) { + DebugTaskManagerImpl* taskManagerImpl = (DebugTaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + struct Context* task = Gearef(context, TaskManager)->task; + TaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnDebugTaskManagerImpl(context, + taskManagerImpl, + task, + Gearef(context, TaskManager)->next, + taskManager); +} + + +__code taskSend(struct DebugTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + printf("[Debug log] taskSend in DebugTaskManager\n"); + // set workerId + if (task->gpu) { + goto taskSend1(); + } else { + goto taskSend2(); + } +} + +__code taskSend1(struct DebugTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + int workerId = taskManager->sendGPUWorkerIndex; + if (++taskManager->sendGPUWorkerIndex >= taskManager->cpu) { + taskManager->sendGPUWorkerIndex = taskManager->gpu; + } + pthread_mutex_unlock(&taskManager->mutex); + struct Queue* queue = taskManager->workers[workerId]->tasks; + // printf("tasks->put taskSend1\n"); + goto queue->put(task, next(...)); +} + +__code taskSend2(struct DebugTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + printf("[Debug log] taskSend2 in DebugTaskManager\n"); + int workerId = taskManager->sendCPUWorkerIndex; + if (++taskManager->sendCPUWorkerIndex >= taskManager->maxCPU) { + taskManager->sendCPUWorkerIndex = taskManager->cpu; + } + pthread_mutex_unlock(&taskManager->mutex); + struct Queue* queue = taskManager->workers[workerId]->tasks; + printf("execute taskSend2\n"); + goto queue->put(task, next(...)); +} + +__code shutdownDebugTaskManagerImpl(struct DebugTaskManagerImpl* taskManager, __code next(...)) { + printf("[Debug log] shutdownDebugTaskManagerImpl in DebugTaskManager\n"); + if (taskManager->taskCount != 0) { + usleep(1000); + goto shutdownDebugTaskManagerImpl(); + } + int i = taskManager->loopCounter; + if (i < taskManager->numWorker) { + struct Queue* tasks = taskManager->workers[i]->tasks; + goto tasks->put(NULL, shutdownDebugTaskManagerImpl1); + } + taskManager->loopCounter = 0; + goto shutdownDebugTaskManagerImpl2(); +} + +__code shutdownDebugTaskManagerImpl1(struct DebugTaskManagerImpl* taskManager, __code next(...)) { + printf("[Debug log] shutdownDebugTaskManagerImpl1 in DebugTaskManager\n"); + taskManager->loopCounter++; + goto shutdownDebugTaskManagerImpl(); +} + +__code shutdownDebugTaskManagerImpl2(struct DebugTaskManagerImpl* taskManager, __code next(...)) { + printf("[Debug log] shutdownDebugTaskManagerImpl2 in DebugTaskManager\n"); + int i = taskManager->loopCounter; + if (i < taskManager->numWorker) { + pthread_join(taskManager->workers[i]->thread, NULL); + taskManager->loopCounter++; + goto shutdownDebugTaskManagerImpl2(); + } + taskManager->loopCounter = 0; + goto next(...); +} diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugTaskManagerImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugTaskManagerImpl.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,19 @@ +typedef struct DebugTaskManagerImpl <> impl TaskManager { + int numWorker; + int sendCPUWorkerIndex; + int sendGPUWorkerIndex; + int taskCount; + pthread_mutex_t mutex; + struct Queue* activeQueue; + struct Worker** workers; + struct Element* taskList; + MemoryPtr mem; // memorylenge for Debugger + StateDB state_db; + int loopCounter; + int cpu; + int gpu; + int io; + int maxCPU; + void (*statefunc)(struct DebugTaskManagerImpl* debugTaskManagerImpl, struct DebugWorker* debugWorker, StateDB now, StateDB next, int flag); + __code next(...); +} DebugTaskManagerImpl; diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/DebugWorker.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/DebugWorker.cbc Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,250 @@ +#include "../../context.h" +#include +#include +#include +#include "../../DebugWorker/state_db.h" + +#interface "TaskManager.h" +#interface "Worker.h" +#interface "Iterator.h" +#interface "Queue.h" + + +static void startWorker(Worker* worker); + +#define INPUT_BUFFER_SIZE 256 +#define NUM_OF_COMMAND 2 + +// workerの作成、初期化、スレッド作成 +Worker* createDebugWorker(struct Context* context, int id, Queue* queue) { + printf("[Debug log] createDebugWorker in DebugWorker\n"); + struct Worker* worker = new Worker(); + struct DebugWorker* debugWorker = new DebugWorker(); + worker->worker = (union Data*)debugWorker; + worker->tasks = queue; + debugWorker->id = id; + + // debugWorker->depth = 0; + // debugWorker->count = 0; + // debugWorker->change = 0; + // debugWorker->debugContext = NULL; + // debugWorker->masterContext = context; //singleton + + debugWorker->loopCounter = 0; + debugWorker->taskManager = context->taskManager; + worker->taskReceive = C_taskReceiveDebugWorker; + worker->shutdown = C_shutdownDebugWorker; + pthread_create(&worker->thread, NULL, (void*)&startWorker, worker); + return worker; +} + +// スレッド用Contextの作成 +static void startWorker(struct Worker* worker) { + printf("[Debug log] startWorker in DebugWorker\n"); + struct DebugWorker* debugWorker = &worker->worker->DebugWorker; + debugWorker->context = NEW(struct Context); + initContext(debugWorker->context); + debugWorker->context->worker = worker; + Gearef(debugWorker->context, Worker)->worker = (union Data*)worker; + Gearef(debugWorker->context, Worker)->tasks = worker->tasks; + printf("[Debug log] finished startWorker in DebugWorker\n"); + goto meta(debugWorker->context, worker->taskReceive); +} + +// task Queueからtaskの取得 +__code taskReceiveDebugWorker(struct DebugWorker* worker, struct Queue* tasks) { + printf("[Debug log] taskReceiveDebugWorker in debug worker\n"); + goto tasks->take(getTaskDebugWorker); +} + +// extern int visit_StateDB(StateDB s, StateDB *parent, StateDB* out, int visit); + +__ncode printDataGear(struct Context* context, enum Code next, char *dataGear_name) { + context->next = next; // remember next Code + + if (strcmp(dataGear_name, "Context") == 0) { + printf("DataGear Name: %s\n", dataGear_name); + printf("next CodeGear: %i\n", context->next); + // printf("Worker: %i\n", context->worker); + + } else if (strcmp(dataGear_name, "Phils") == 0) { + printf("DataGear Name: %s\n", dataGear_name); + printf("DataGear Address: %p\n", context->data); + printf("Phils Address: %p\n", Gearef(context, Phils)); + printf("putdown_rfork: %i\n", Gearef(context, Phils)->putdown_rfork); + printf("thinking: %i\n", Gearef(context, Phils)->thinking); + printf("pickup_lfork: %i\n", Gearef(context, Phils)->pickup_lfork); + printf("pickup_rfork: %i\n", Gearef(context, Phils)->pickup_rfork); + printf("eating: %i\n", Gearef(context, Phils)->eating); + printf("next: %i\n", Gearef(context, Phils)->next); + } else { + printf("invalid options. Please enter correct DataGear name option.\n"); + } + goto debugMeta(context, context->next); +} + +__ncode debugMeta(struct Context* context, enum Code next) { + printf("[Debug log] debugMeta in DebugWorker\n"); + context->next = next; // remember next Code Gear + printf("start get debugWorker\n"); + struct DebugWorker* debugWorker = (struct DebugWorker*) Gearef(context, Worker); + // struct DebugWorker* debugWorker = (struct DebugWorker*) context->worker->worker; + printf("finish get debugWorker\n"); + StateNode st; + StateDB out = &st; + struct Element* list = NULL; + struct DebugTaskManagerImpl* debugTaskManagerImpl = (struct DebugTaskManagerImpl *)debugWorker->taskManager->taskManager; + out->memory = debugTaskManagerImpl->mem; + out->hash = get_memory_hash(debugTaskManagerImpl->mem,0); + // debugTaskManagerImpl->statefunc(debugTaskManagerImpl, debugWorker, debugWorker->parent, out, debugWorker->checking); + + char command_arr[NUM_OF_COMMAND][INPUT_BUFFER_SIZE]; + + while(1) { + printf("\n(Gears Debugger) "); + // ユーザーインプット処理 + int i=0; + char user_input[INPUT_BUFFER_SIZE], *command; + + fgets(user_input, sizeof(user_input), stdin); + command = strtok(user_input, " \n"); + + while (command != NULL) { + strcpy(command_arr[i], command); + command = strtok(NULL, " \n"); + i++; + } + + // checking for input + for (i = 0; i < NUM_OF_COMMAND; i++) { + printf("command_arr[%d] : %s\n", i, command_arr[i]); + } + + // next + // nextする前にstateDBへ保存する処理を書きたい + if (strcmp(command_arr[0], "next") == 0 || strcmp(command_arr[0], "n") == 0) { + dump_memory(debugTaskManagerImpl->mem); + // printf(" flag %0x %p -> %p hash %0x \n", out->flag, debugWorker->parent, out, out->hash); + goto meta(context, context->next); + // quit + } else if (strcmp(command_arr[0], "quit") == 0 || strcmp(command_arr[0], "q") == 0) { + printf("quit program\n"); + exit(0); + // help + } else if (strcmp(command_arr[0], "help") == 0 || strcmp(command_arr[0], "h") == 0){ + printf("Debugger commands:\n"); + printf("next, n:\t Go next step.\n"); + printf("help, h:\t Show a list of all debugger commands\n"); + printf("quit, q:\t Quit program.\n"); + printf("pd:\t\t Show DataGear. Specify the datagear name. ex) pd Phils\n"); + // pd(print DataGear) + } else if (strcmp(command_arr[0], "pd") == 0){ + goto printDataGear(context, context->next, &command_arr[1]); + //others + } else { + printf("invalid input. Please enter correct debugger commands.\n"); + } + } +} + +__code getTaskDebugWorker(struct DebugWorker* debugWorker, struct Context* task, struct Worker* worker) { + printf("[Debug log] getTaskDebugWorker in DebugWorker\n"); + if (!task) { + printf("debug worker take task finished\n"); + goto worker->shutdown(); + } + printf("debug worker get task\n"); + task->worker = worker; + enum Code taskCg = task->next; + task->next = C_odgCommitDebugWorker; // commit outputDG after task exec + goto meta(task, taskCg); // switch task context +} + +__code getTaskDebugWorker_stub(struct Context* context) { + DebugWorker* debugWorker = (DebugWorker*)GearImpl(context, Worker, worker); + Worker* worker = &Gearef(context,Worker)->worker->Worker; + struct Context* task = &Gearef(context, Queue)->data->Context; + goto getTaskDebugWorker(context, debugWorker, task, worker); +} + +__code odgCommitDebugWorker(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker in DebugWorker\n"); + if (task->iterate) { + struct Iterator* iterator = task->iterator; + goto iterator->barrier(task, odgCommitDebugWorker1, odgCommitDebugWorker6); + } else { + goto odgCommitDebugWorker1(); + } +} + +__code odgCommitDebugWorker_stub(struct Context* context) { + // switch worker context + struct Context* workerContext = context->worker->worker->DebugWorker.context; + Gearef(workerContext, Worker)->worker = (union Data*)context->worker; + Gearef(workerContext, Worker)->task = context; + DebugWorker* debugWorker = (DebugWorker*)GearImpl(workerContext, Worker, worker); + goto odgCommitDebugWorker(workerContext, + debugWorker, + context); +} + +__code odgCommitDebugWorker1(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker1 in DebugWorker\n"); + int i = worker->loopCounter; + if (task->odg+i < task->maxOdg) { + goto odgCommitDebugWorker2(); + } + worker->loopCounter = 0; + struct TaskManager* taskManager = task->taskManager; + goto taskManager->decrementTaskCount(odgCommitDebugWorker6); +} + +__code odgCommitDebugWorker2(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker2 in DebugWorker\n"); + int i = worker->loopCounter; + struct Queue* queue = GET_WAIT_LIST(task->data[task->odg+i]); + goto queue->isEmpty(odgCommitDebugWorker3, odgCommitDebugWorker5); +} + +__code odgCommitDebugWorker3(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker3 in DebugWorker\n"); + int i = worker->loopCounter; + struct Queue* queue = GET_WAIT_LIST(task->data[task->odg+i]); + goto queue->take(odgCommitDebugWorker4); +} + +__code odgCommitDebugWorker4(struct DebugWorker* worker, struct Context* task, struct Context* waitTask) { + printf("[Debug log] odgCommitDebugWorker4 in DebugWorker\n"); + if (__sync_fetch_and_sub(&waitTask->idgCount, 1) == 1) { // atomic decrement idg counter(__sync_fetch_and_sub function return initial value of waitTask->idgCount point) + struct TaskManager* taskManager = waitTask->taskManager; + goto taskManager->spawn(waitTask, odgCommitDebugWorker2); + } + goto odgCommitDebugWorker2(); +} + +__code odgCommitDebugWorker4_stub(struct Context* context) { + DebugWorker* debugWorker = (DebugWorker*)GearImpl(context, Worker, worker); + struct Context* task = Gearef(context, Worker)->task; + struct Context* waitTask = &Gearef(context, Queue)->data->Context; + goto odgCommitDebugWorker4(context, + debugWorker, + task, + waitTask); +} + +__code odgCommitDebugWorker5(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker5 in DebugWorker\n"); + worker->loopCounter++; + goto odgCommitDebugWorker1(); +} + +__code odgCommitDebugWorker6(struct DebugWorker* worker, struct Context* task) { + printf("[Debug log] odgCommitDebugWorker6 in DebugWorker\n"); + struct Worker* taskWorker = task->worker; + goto taskWorker->taskReceive(taskWorker->tasks); +} + +__code shutdownDebugWorker(struct DebugWorker* worker) { + printf("[Debug log] shutdownDebugWorker in DebugWorker\n"); + goto exit_code(); +} diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/DebugWorker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/DebugWorker.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,23 @@ +// #include "state_db.h" +// #include "memory.h" +// #include "TaskIterator.h" + +typedef struct DebugWorker <> { + pthread_mutex_t mutex; + pthread_cond_t cond; + struct Context* context; //simulated task + // struct Context* mcContext; // context for mcWorker + // struct Context* masterContext; // context for McTaskManager (singleton) + struct TaskManager* taskManager; + int id; + int loopCounter; + // struct Queue* mcQueue; // simulated task queue par thread + // TaskIterator* task_iter; + StateDB parent; + // StateDB root; + // int depth; + int visit; + // int count; + // int change; // state db flag is changed + int checking; // state checking phase +} DebugWorker; diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/TaskIterator.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/TaskIterator.c Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,38 @@ +#include +#include "../context.h" +#include "TaskIterator.h" +#include "state_db.h" + +TaskIterator* createQueueIterator(Element* elements, StateDB s, TaskIterator* prev) { + TaskIterator* new = (TaskIterator*)calloc(1, sizeof(TaskIterator)); + if (!new) exit(1); + new->prev = prev; + new->state = s; // + new->list = elements; + return new; +} + +Element* takeNextIterator(TaskIterator* iterator) { + struct Element* elem = iterator->list; + if (!elem) { + return NULL; + } + struct Element* next = elem->next; + if (next == NULL) { + return NULL; + } + iterator->list = next; + return next; +} + +int iteratorLength(TaskIterator* iterator) { + int i = 0; + struct Element* elem = iterator->list; + for(; elem; elem = elem->next) i++; + return i; +} + +void freeIterator(TaskIterator* iterator) { + free(iterator); +} + diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/TaskIterator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/TaskIterator.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,8 @@ +#ifndef TASKITERATOR +typedef struct TaskIterator { + struct TaskIterator* prev; + StateDB state; + struct Element* list; +} TaskIterator; +#define TASKITERATOR +#endif diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/crc32.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/crc32.c Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,78 @@ +/* + $Id: crc32.c,v 1.1.1.1 2007/03/06 06:34:39 atsuki Exp $ + Shinji KONO + based on open source CRCtextDlg.cpp Richard A. Ellingson + + This is generated by Perl, do not edit this. Edit Perl script. + */ + +static unsigned crc32_table[256] = { + 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b, + 0x1a864db2,0x1e475005,0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, + 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,0x4c11db70,0x48d0c6c7, + 0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, + 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3, + 0x709f7b7a,0x745e66cd,0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, + 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,0xbe2b5b58,0xbaea46ef, + 0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, + 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb, + 0xceb42022,0xca753d95,0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, + 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,0x34867077,0x30476dc0, + 0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, + 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4, + 0x0808d07d,0x0cc9cdca,0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, + 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,0x5e9f46bf,0x5a5e5b08, + 0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, + 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc, + 0xb6238b25,0xb2e29692,0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, + 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,0xe0b41de7,0xe4750050, + 0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, + 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34, + 0xdc3abded,0xd8fba05a,0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, + 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,0x4f040d56,0x4bc510e1, + 0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, + 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5, + 0x3f9b762c,0x3b5a6b9b,0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, + 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,0xf12f560e,0xf5ee4bb9, + 0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, + 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd, + 0xcda1f604,0xc960ebb3,0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, + 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,0x9b3660c6,0x9ff77d71, + 0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, + 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2, + 0x470cdd2b,0x43cdc09c,0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, + 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,0x119b4be9,0x155a565e, + 0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, + 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a, + 0x2d15ebe3,0x29d4f654,0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, + 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,0xe3a1cbc1,0xe760d676, + 0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, + 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662, + 0x933eb0bb,0x97ffad0c,0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, + 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4 +}; + + + +// Once the lookup table has been filled in by the two functions above, +// this function creates all CRCs using only the lookup table. + +// Be sure to use unsigned variables, +// because negative values introduce high bits +// where zero bits are required. +// Start out with all bits set high. + +unsigned Get_CRC(unsigned char *buffer,int len,unsigned ulCRC) +{ + // Perform the algorithm on each character + // in the string, using the lookup table values. + + while(len-->0) { + ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ *buffer++]; + } + // Exclusive OR the result with the beginning value. + return ulCRC ^ 0xffffffff; +} + +// ******* End custom code ******* + diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/crc32.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/crc32.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,8 @@ +/* + $Id: crc32.h,v 1.1.1.1 2007/03/06 06:34:39 atsuki Exp $ + Shinji KONO + based on open source + */ + +extern unsigned Get_CRC(unsigned char *buffer,int len, unsigned ulCRC); + diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/memory.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/memory.c Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,379 @@ +/* + + memory fragment management library + + Shinji Kono (2006) + + usage: + + MemoryPtr db = 0; + add_memory(address,length,&db); + + memory pattern is copyied and stored in a binary tree in db. + All patterns are shared. + + memory pattern database (binary tree by pattern) + + + */ + +#include +#include +#include "memory.h" +#include "crc32.h" +#include + +#define MEMORY_REPORT 1 + +#if MEMORY_REPORT +int memory_header; +int memcmp_count; +int memory_body; +int restore_count; +int restore_size; +int range_count; +int range_size; +#endif + +extern void die_exit(char *); + +void +die_exit(char *msg) +{ + fprintf(stderr,"%s\n",msg); + exit(1); +} + +// static MemoryPtr memory_root; + + +/* + + make memory fragment as a part of the program state + + */ + +MemoryPtr +create_memory(void *adr, int length) +{ + MemoryPtr m = (MemoryPtr)malloc(sizeof(Memory)); + if (!m) die_exit("Cann't alloc memory list."); + m->left = m->right = 0; + m->length = length; + m->adr = m->body = adr; +#if MEMORY_REPORT + memory_header++; +#endif + return m; +} + +/* + + Compute hash value of a memory fragment + + */ + +unsigned +compute_memory_hash1(MemoryPtr m,unsigned hash) +{ + return Get_CRC((unsigned char *)m->adr,m->length, hash); +} + +void +free_memory(MemoryPtr m) +{ + m->left = m->right = 0; + m->adr = m->body = 0; + free(m); +} + +/* + + Compare memory contents ( doesn't care about its address ) + + */ + +int +cmp_content(MemoryPtr a,MemoryPtr b) +{ + if (a->length != b->length) { + if (a->length > b->length) { + return 1; + } else { + return -1; + } + } + if (a->hash == b->hash) { +#if MEMORY_REPORT + memcmp_count ++; +#endif + return memcmp(a->body,b->body,a->length); + } else if (a->hash > b->hash) { + return 1; + } else { + return -1; + } +} + +/* + + Compare entire memory contents ( doesn't care about its address ) + + */ + +static int +cmp_memory1(MemoryPtr a,MemoryPtr b) +{ + int r; + if ((r=cmp_content(a,b))) return r; + + if (a->adr==b->adr) { + return 0; + } + return (a->adr > b->adr) ? 1 : -1; +} + +int +cmp_memory(MemoryPtr a,MemoryPtr b) +{ + int r; + while(1) { + if ((r=cmp_memory1(a,b))) return r; + if (a->left && b->left) { + if ((r=cmp_memory(a->left,b->left))) return r; + } else if (a->left || b->left) { + return (a->left > b->left)? 1 : -1; + } + if (a->right && b->right) { + a = a->right; b = b->right; + // recursive loop + } else if (a->right || b->right) { + return (a->right > b->right)? 1 : -1; + } else { + return 0; // singleton + } + } +} + +/* + Make a copy of real memory fragments + */ + +MemoryPtr +copy_memory1(MemoryPtr m) +{ + MemoryPtr new = create_memory(m->adr,m->length); + void *p = (void *)malloc(m->length); + if (!p) { + die_exit("can't alloc memory body"); + return 0; + } +#if MEMORY_REPORT + memory_body += m->length; +#endif + memcpy(p,m->adr,m->length); + m->body = new->body = p; // abondon original memory pattern + new->hash = m->hash; + return new; +} + +MemoryPtr +copy_memory(MemoryPtr m, MemoryPtr *db) +{ + MemoryPtr new, out; + if (!m) return m; + new = create_memory(m->adr,m->length); + new->hash = m->hash; + // look up is necessary to share its memory pattern + memory_lookup(new, db, copy_memory1, &out); + if (m->left) new->left = copy_memory(m->left, db); + if (m->right) new->right = copy_memory(m->right, db); + return new; +} + +/* + restore copied memory save to the original addresses + */ + +void +restore_memory(MemoryPtr m) +{ + while (m) { + memcpy(m->adr,m->body,m->length); +#if MEMORY_REPORT + restore_count ++; + restore_size += m->length; +#endif + if (m->left) restore_memory(m->left); + m = m->right; + } +} + + +/* + get hash for all memeory fragments + initial value of hash should be zero + */ + +unsigned +get_memory_hash(MemoryPtr m, unsigned hash) +{ + if (!m) return hash; + if (m->left) hash = get_memory_hash(m->left, hash); + m->hash = compute_memory_hash1(m, 0xffffffff); // for each memory segment + hash = Get_CRC((unsigned char *)&m->hash,sizeof(m->hash), hash); // for entire chain + if (m->right) hash = get_memory_hash(m->right, hash); + return hash; +} + +/* + add modified memory fragments to the pattern database + */ + +MemoryPtr +add_memory(void *ptr,int length, MemoryPtr *parent) +{ + Memory m, *out; + m.adr = m.body = ptr; + m.length = length; + m.left = m.right = 0; + m.hash = compute_memory_hash1(&m, 0xffffffff); + memory_lookup(&m, parent, copy_memory1, &out); + return out; +} + +int +memory_lookup(MemoryPtr m, MemoryPtr *parent, + MemoryPtr (*new_memory)(MemoryPtr), MemoryPtr *out) +{ + MemoryPtr db; + int r; + + while(1) { + db = *parent; + if (!db) { + /* not found */ + if (new_memory && out) { + db = new_memory(m); + db->left = db->right = 0; + *out = *parent = db; + } + return 0; + } + if(!(r = cmp_memory1(m,db))) { + /* bingo */ + if (out) { + *out = db; + } + return 1; + } else if (r>0) { + parent = &db->left; + } else if (r<0) { + parent = &db->right; + } + } + /* !NOT REACHED */ +} + +/* + memory range list management for state registration + this list points the real memory + */ + +MemoryPtr +add_memory_range(void *ptr,int length, MemoryPtr *parent) +{ + Memory m, *out; + m.adr = ptr; + m.length = length; + m.left = m.right = 0; + + memory_range_lookup(&m, parent, &out); + return out; +} + +static int +cmp_range(MemoryPtr a,MemoryPtr b) +{ + if (a->adr==b->adr) { + if (a->length != b->length) + die_exit("memory range inconsitency"); + return 0; + } + return (a->adr > b->adr) ? 1 : -1; +} + +int +memory_range_lookup(MemoryPtr m, MemoryPtr *parent, MemoryPtr *out) +{ + MemoryPtr db; + int r; + + while(1) { + db = *parent; + if (!db) { + /* not found */ + if (out) { + db = create_memory(m->adr, m->length); + *out = *parent = db; + } +#if MEMORY_REPORT + range_count++; + range_size+=m->length; +#endif + return 0; + } + if(!(r = cmp_range(m,db))) { + /* bingo (actually an error) */ + if (out) { + *out = db; + } + return 1; + } else if (r>0) { + parent = &db->left; + } else if (r<0) { + parent = &db->right; + } + } + /* !NOT REACHED */ +} + +/* + dump memory + */ + +void +dump_memory(MemoryPtr m) +{ + while (m) { + // printf("\n%p : ",m->adr); + unsigned char *p = (unsigned char *)m->adr; + for(int i=0; ilength ;i++) { + printf("%02x",p[i]); + if ((i+1)%4==0) putchar(' '); + } + if (m->left) dump_memory(m->left); + m = m->right; + } +} + + +/* + */ + +void +memory_usage() +{ +#if MEMORY_REPORT + printf(" memory_header %d\n",memory_header); + printf(" memcmp_count %d\n",memcmp_count); + printf(" memory_body %d\n",memory_body); + printf(" restore_count %d\n",restore_count); + printf(" restore_size %d\n",restore_size); + printf(" range_count %d\n",range_count); + printf(" range_size %d\n",range_size); +#endif +} + + +/* end */ diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/memory.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/memory.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,60 @@ +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + + +typedef struct memory { + void *adr; + int length; + void *body; + int hash; + struct memory *left,*right; +} Memory, *MemoryPtr; + +extern void die_exit(char *); + +extern MemoryPtr +create_memory(void *adr, int length); + +extern unsigned +compute_memory_hash1(MemoryPtr m, unsigned hash); + +extern void +free_memory(MemoryPtr m); + +extern int +cmp_content(MemoryPtr a,MemoryPtr b); + +extern int +cmp_memory(MemoryPtr a,MemoryPtr b); + +extern MemoryPtr +copy_memory(MemoryPtr m, MemoryPtr *db); + +extern void +restore_memory(MemoryPtr m) ; + +extern unsigned +get_memory_hash(MemoryPtr m,unsigned hash); + +MemoryPtr +add_memory(void *ptr,int length, MemoryPtr *parent); + +extern int +memory_lookup(MemoryPtr m, MemoryPtr *parent, + MemoryPtr (*new_memory)(MemoryPtr), MemoryPtr *out); + +extern MemoryPtr +add_memory_range(void *ptr,int length, MemoryPtr *parent); + +extern int +memory_range_lookup(MemoryPtr m, MemoryPtr *parent, MemoryPtr *out); + +extern void +memory_usage(); + +extern void +dump_memory(MemoryPtr m); + + +#endif +/* end */ diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/state_db.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/state_db.c Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,94 @@ +#include + +#include "state_db.h" +#include "memory.h" + +StateDB +create_stateDB() +{ + StateDB s = (StateDB)malloc(sizeof(StateNode)); + if (!s) die_exit("Cann't alloc state db node."); + return s; +} + +static MemoryPtr mem_db; + +static int state_count0; + +void +reset_state_count() +{ + state_count0 = 0; +} + +int +state_count() +{ + return state_count0; +} + + +/* + + lookup_StateDB(struct state *s, StateDB *parent, StatePtr *out) + + s->memory points the real memory + if s is new, it is copied in the database (parent). + if s is in the database, existing state is returned. + + if return value is 0, it returns new state. + if out is null, no copy_state is created. (lookup mode) + + Founded state or newly created state is returned in out. + + */ + +int +lookup_StateDB(StateDB s, StateDB *parent, StateDB *out) +{ + StateDB db; + int r; + + while(1) { + db = *parent; + if (!db) { + /* not found */ + if (out) { + db = create_stateDB(); + db->left = db->right = 0; + db->memory = copy_memory(s->memory,&mem_db); + db->hash = s->hash; + state_count0 ++; + *parent = db; + *out = db; + } + return 0; + } + if (s->hash == db->hash) { + r = cmp_memory(s->memory,db->memory); + } else + r = (s->hash > db->hash)? 1 : -1; + if(!r) { + /* bingo */ + if (out) *out = db; + return 1; + } else if (r>0) { + parent = &db->left; + } else if (r<0) { + parent = &db->right; + } + } +} + +int +visit_StateDB(StateDB s, StateDB *parent, StateDB* out, int visit) +{ + int exists = lookup_StateDB(s,parent,out); + if (!exists) return 0; + if ((*out)->visit >= visit) { + return 1; + } + (*out)->visit = visit; + return 0; + } +/* end */ diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/DebugWorker/state_db.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/DebugWorker/state_db.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,21 @@ +#ifndef _STATE_DB_H_ +#define _STATE_DB_H_ + +typedef struct state_db { + struct memory *memory; + unsigned hash; + int visit; // visiting count for repeating search + int flag; // CTL state + struct state_db *left; + struct state_db *right; +} StateNode, *StateDB; + +extern int +lookup_StateDB(StateDB s, StateDB *db, StateDB *out); + +extern int state_count(); +extern void reset_state_count(); + + + +#endif diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/examples/DebughelloWorld/Hello.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/examples/DebughelloWorld/Hello.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,7 @@ +typedef struct Hello <> { + union Data* hello; + char* string; + __code h(Impl* hello, __code next(...)); + __code w(Impl* hello, __code next(...)); + __code next(...); +} Hello; diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/examples/DebughelloWorld/HelloImpl.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/examples/DebughelloWorld/HelloImpl.cbc Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,42 @@ +#include "../../../context.h" +#include +#impl "Hello.h" as "HelloImpl.h" +#interface "Hello.h" +#interface "Worker.h" +#interface "TaskManager.h" + +extern __code debugMeta(struct Context*, enum Code); + +// ---- +// typedef struct HelloImpl <> impl Hello { +// char* hString; +// char* wString; +// } HelloImpl; +// ---- + +Hello* createHelloImpl(struct Context* context) { + printf("[Debug log] createHelloImpl in HelloImpl\n"); + struct Hello* hello = new Hello(); + struct HelloImpl* hello_impl = new HelloImpl(); + hello->hello = (union Data*)hello_impl; + hello->string = NULL; + hello_impl->hString = NULL; + hello_impl->wString = NULL; + hello->h = C_hHelloImpl; + hello->w = C_wHelloImpl; + return hello; +} +__code h(struct HelloImpl* hello, __code next(...)) { + printf("[Debug log] h in HelloImpl\n"); + hello->hString = "Hello, "; //createImpl部分では_implなのだが動く + printf("%s", hello->hString); + goto w(hello, next); +} + +__code w(struct HelloImpl* hello, __code next(...)) { + printf("[Debug log] w in HelloImpl\n"); + hello->wString = "World.\n"; + printf("%s", hello->wString); + goto next(...); +} + diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/examples/DebughelloWorld/HelloImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/examples/DebughelloWorld/HelloImpl.h Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,4 @@ +typedef struct HelloImpl <> impl Hello { + char* hString; + char* wString; +} HelloImpl; diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/examples/DebughelloWorld/main.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/examples/DebughelloWorld/main.cbc Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,73 @@ +#include +#include +#include +#include + + +#include "../../../context.h" +#interface "TaskManager.h" +#interface "Hello.h" + +int cpu_num = 1; +int length = 102400; +int split = 8; +int* array_ptr; +int gpu_num = 0; +int CPU_ANY = -1; +int CPU_CUDA = -1; + +__code initDataGears(struct LoopCounter* loopCounter, struct TaskManager* taskManager) { + printf("[Debug log] initDataGears in main\n"); + // loopCounter->tree = createRedBlackTree(context); + loopCounter->i = 0; + taskManager->taskManager = (union Data*)createDebugTaskManagerImpl(context, cpu_num, gpu_num, 0); + goto code1(); +} + +__code code1(struct LoopCounter* loopCounter) { + printf("[Debug log] code1 in main\n"); + printf("cpus:\t\t%d\n", cpu_num); + printf("gpus:\t\t%d\n", gpu_num); + printf("length:\t\t%d\n", length); + printf("length/task:\t%d\n", length/split); + goto createTask1(); +} + + +__code createTask1(struct LoopCounter* loopCounter, struct TaskManager* taskManager) { + printf("[Debug log] createTask1 in main\n"); + Hello* hello = createHelloImpl(context); + goto hello->h(code2); +} + + +__code code2(struct TaskManager* taskManager) { + printf("[Debug log] code2 in main\n"); + goto taskManager->shutdown(exit_code); +} + +__code code2_stub(struct Context* context) { + goto code2(context, &Gearef(context, TaskManager)->taskManager->TaskManager); +} + +void init(int argc, char** argv) { + printf("[Debug log] init in main\n"); + for (int i = 1; argv[i]; ++i) { + if (strcmp(argv[i], "-cpu") == 0) + cpu_num = (int)atoi(argv[i+1]); + else if (strcmp(argv[i], "-l") == 0) + length = (int)atoi(argv[i+1]); + else if (strcmp(argv[i], "-s") == 0) + split = (int)atoi(argv[i+1]); + else if (strcmp(argv[i], "-cuda") == 0) { + gpu_num = 1; + CPU_CUDA = 0; + } + } +} + +int main(int argc, char** argv) { + printf("[Debug log] main in main\n"); + init(argc, argv); + goto initDataGears(); +} diff -r a9c630cc1c65 -r e6778c866876 src/parallel_execution/examples/DebughelloWorld/meta.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/examples/DebughelloWorld/meta.pm Tue Jan 18 19:54:28 2022 +0900 @@ -0,0 +1,17 @@ +package meta; +use strict; +use warnings; + +sub replaceMeta { + return ( + [qr/HelloImpl/ => \&generatedebugMeta], + ); +} + +#my ($currentCodeGearName, $context, $next) = @_; + +sub generatedebugMeta { + my ($context, $next) = @_; + return "goto debugMeta($context, $next);"; +} +1;