#include "../../context.h" #include #include #include #include "../../DebugWorker/state_db.h" #interface "TaskManager.h" #interface "Worker.h" #interface "Iterator.h" #interface "Queue.h" #interface "SingleLinkedQueue.h" static void startWorker(Worker* worker); static int dump = 1; #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); // context->worker = 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; // init state DB struct DebugTaskManagerImpl* debugTaskManagerImpl = (struct DebugTaskManagerImpl *)debugWorker->taskManager->taskManager; StateNode st ; StateDB out = &st; out->memory = debugTaskManagerImpl->mem; out->hash = get_memory_hash(debugTaskManagerImpl->mem,0); lookup_StateDB(out, &debugTaskManagerImpl->state_db, &out); if (dump) { dump_memory(debugTaskManagerImpl->mem); printf(" flag %0x %p -> %p hash %0x \n", out->flag, debugWorker->parent, out, out->hash); } 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 printTrace(struct Context* context, enum Code next) { printf("[Debug log] print trace\n"); context->next = next; // remember next Code // TODO: stateDBに保存したメモリ状態をトレースとして表示させる struct DebugWorker* debugWorker = (struct DebugWorker*) context->worker->worker; struct DebugTaskManagerImpl* debugTaskManagerImpl = (struct DebugTaskManagerImpl *)debugWorker->taskManager->taskManager; 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 struct DebugWorker* debugWorker = (struct DebugWorker*) context->worker->worker; 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); int found = visit_StateDB(out, &debugTaskManagerImpl->state_db, &out,debugWorker->visit); // 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) { 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]); } else if (strcmp(command_arr[0], "pt") == 0){ goto printTrace(context, context->next); } else if (strcmp(command_arr[0], "dump") == 0){ dump_memory(debugTaskManagerImpl->mem); //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(); }