# HG changeset patch # User anatofuz # Date 1611471160 -32400 # Node ID 5125f75dd6f26040e489f35fca8ba1bdcd31b602 # Parent e2a0e5a65a3de612104087c7883486ceadc37cb7 impl MCTask diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/CMakeLists.txt --- a/src/parallel_execution/CMakeLists.txt Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/CMakeLists.txt Sun Jan 24 15:52:40 2021 +0900 @@ -153,7 +153,7 @@ TARGET DPP2 SOURCES - TaskManagerImpl.cbc CPUWorker.cbc SynchronizedQueue.cbc examples/DPP2/AtomicTImpl.cbc SingleLinkedStack.cbc examples/DPP2/PhilsImpl.cbc examples/DPP2/main.cbc examples/DPP2/ForkImpl.cbc ModelChecking/crc32.c ModelChecking/memory.c ModelChecking/state_db.c AtomicReference.cbc + TaskManagerImpl.cbc CPUWorker.cbc SynchronizedQueue.cbc examples/DPP2/AtomicTImpl.cbc SingleLinkedStack.cbc examples/DPP2/PhilsImpl.cbc examples/DPP2/main.cbc examples/DPP2/ForkImpl.cbc ModelChecking/crc32.c ModelChecking/memory.c ModelChecking/state_db.c AtomicReference.cbc ModelChecking/MCWorker.cbc ) GearsCommand( diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/MCTaskManagerImpl.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/MCTaskManagerImpl.cbc Sun Jan 24 15:52:40 2021 +0900 @@ -0,0 +1,206 @@ +#include "../context.h" +#interface "TaskManager.h" +#interface "Iterator.h" +#interface "Queue.h" +#interface "Worker.h" + +#include +#include + +void createWorkers(struct Context* context, TaskManagerImpl* taskManager); + +TaskManager* createMCTaskManagerImpl(struct Context* context, int numCPU, int numGPU, int numIO) { + struct TaskManager* taskManager = new TaskManager(); + taskManager->spawnTasks = C_spawnTasksTaskManagerImpl; + taskManager->spawn = C_spawnTaskManagerImpl; + taskManager->shutdown = C_shutdownTaskManagerImpl; + taskManager->incrementTaskCount = C_incrementTaskCountTaskManagerImpl; + taskManager->decrementTaskCount = C_decrementTaskCountTaskManagerImpl; + taskManager->setWaitTask = C_setWaitTaskTaskManagerImpl; + struct MCTaskManagerImpl* taskManagerImpl = new TaskManagerImpl(); + // 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; + createWorkers(context, taskManagerImpl); + taskManager->taskManager = (union Data*)taskManagerImpl; + return taskManager; +} + +void createWorkers(struct Context* context, MCMCTaskManagerImpl* taskManager) { + 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*)createCPUWorker(context, i, queue); +#endif + } + for (;imaxCPU;i++) { + Queue* queue = createSynchronizedQueue(context); + taskManager->workers[i] = (Worker*)createCPUWorker(context, i, queue); + } +} + +__code spawnTasksMCTaskManagerImpl(struct TaskManagerImpl* taskManager, struct Element* taskList, __code next1(...)) { + taskManager->taskList = taskList; + goto spawnTasksMCTaskManagerImpl1(); +} + +__code spawnTasksMCTaskManagerImpl1(struct TaskManagerImpl* taskManagerImpl, struct TaskManager* taskManager) { + if (taskManagerImpl->taskList == NULL) { + goto spawnTasksMCTaskManagerImpl2(); + } + struct Context* task = (struct Context*)taskManagerImpl->taskList->data; + taskManagerImpl->taskList = taskManagerImpl->taskList->next; + goto taskManager->setWaitTask(task, spawnTasksMCTaskManagerImpl1); +} + +__code spawnTasksMCTaskManagerImpl1_stub(struct Context* context) { + MCTaskManagerImpl* taskManagerImpl = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + MCTaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnTasksMCTaskManagerImpl1(context, taskManagerImpl, taskManager); +} + +__code spawnTasksMCTaskManagerImpl2(struct TaskManagerImpl* taskManager, struct Element* taskList, __code next1(...)) { + taskManager->taskList = taskList; + goto spawnTasksMCTaskManagerImpl3(); +} + +__code spawnTasksMCTaskManagerImpl3(struct TaskManagerImpl* taskManagerImpl, __code next1(...), struct TaskManager* taskManager) { + if (taskManagerImpl->taskList == NULL) { + goto next1(...); + } + struct Context* task = (struct Context*)taskManagerImpl->taskList->data; + taskManagerImpl->taskList = taskManagerImpl->taskList->next; + goto taskManager->spawn(task, spawnTasksMCTaskManagerImpl3); +} + +__code spawnTasksMCTaskManagerImpl3_stub(struct Context* context) { + MCTaskManagerImpl* taskManagerImpl = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + enum Code next1 = Gearef(context, MCTaskManager)->next1; + MCTaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnTasksMCTaskManagerImpl3(context, taskManagerImpl, next1, taskManager); +} + +__code setWaitTaskMCTaskManagerImpl(struct TaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + 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, setWaitTaskMCTaskManagerImpl); + } + taskManager->loopCounter = 0; + goto incrementTaskCountMCTaskManagerImpl(); +} + +__code incrementTaskCountMCTaskManagerImpl(struct TaskManagerImpl* taskManager, __code next(...)) { + __sync_fetch_and_add(&taskManager->taskCount, 1); + goto next(...); +} + +__code decrementTaskCountMCTaskManagerImpl(struct TaskManagerImpl* taskManager, __code next(...)) { + __sync_fetch_and_sub(&taskManager->taskCount, 1); + goto next(...); +} + +__code spawnMCTaskManagerImpl(struct TaskManagerImpl* taskManagerImpl, struct Context* task, __code next(...), struct TaskManager* taskManager) { + 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 spawnMCTaskManagerImpl_stub(struct Context* context) { + MCTaskManagerImpl* taskManagerImpl = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + struct Context* task = Gearef(context, MCTaskManager)->task; + MCTaskManager* taskManager = &Gearef(context, TaskManager)->taskManager->TaskManager; + goto spawnMCTaskManagerImpl(context, + taskManagerImpl, + task, + Gearef(context, MCTaskManager)->next, + taskManager); +} + + +__code taskSend(struct MCTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + // set workerId + if (task->gpu) { + goto taskSend1(); + } else { + goto taskSend2(); + } +} + +__code taskSend1(struct MCTaskManagerImpl* 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; + goto queue->put(task, next(...)); +} + +__code taskSend2(struct MCTaskManagerImpl* taskManager, struct Context* task, __code next(...)) { + 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; + goto queue->put(task, next(...)); +} + +__code shutdownMCTaskManagerImpl(struct TaskManagerImpl* taskManager, __code next(...)) { + if (taskManager->taskCount != 0) { + usleep(1000); + goto shutdownMCTaskManagerImpl(); + } + int i = taskManager->loopCounter; + if (i < taskManager->numWorker) { + struct Queue* tasks = taskManager->workers[i]->tasks; + goto tasks->put(NULL, shutdownMCTaskManagerImpl1); + } + + taskManager->loopCounter = 0; + goto shutdownMCTaskManagerImpl2(); +} + +__code shutdownMCTaskManagerImpl1(struct TaskManagerImpl* taskManager, __code next(...)) { + taskManager->loopCounter++; + goto shutdownMCTaskManagerImpl(); +} + +__code shutdownMCTaskManagerImpl2(struct TaskManagerImpl* taskManager, __code next(...)) { + int i = taskManager->loopCounter; + if (i < taskManager->numWorker) { + pthread_join(taskManager->workers[i]->thread, NULL); + taskManager->loopCounter++; + goto shutdownMCTaskManagerImpl2(); + } + taskManager->loopCounter = 0; + goto next(...); +} diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/MCTaskManagerImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/MCTaskManagerImpl.h Sun Jan 24 15:52:40 2021 +0900 @@ -0,0 +1,16 @@ +typedef struct MCTaskManagerImpl <> impl MCTaskManager { + int numWorker; + int sendCPUWorkerIndex; + int sendGPUWorkerIndex; + int taskCount; + pthread_mutex_t mutex; + struct Queue* activeQueue; + struct Worker** workers; + struct Element* taskList; + int loopCounter; + int cpu; + int gpu; + int io; + int maxCPU; + __code next(...); +} MCTaskManagerImpl; diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/MCWorker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/MCWorker.h Sun Jan 24 15:52:40 2021 +0900 @@ -0,0 +1,7 @@ +typedef struct MCWorker <> { + pthread_mutex_t mutex; + pthread_cond_t cond; + struct Context* context; + int id; + int loopCounter; +} MCWorker; diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/ModelChecking/MCWorker.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parallel_execution/ModelChecking/MCWorker.cbc Sun Jan 24 15:52:40 2021 +0900 @@ -0,0 +1,124 @@ +#include "../../context.h" +#interface "TaskManager.h" +#interface "Worker.h" +#interface "Iterator.h" +#interface "Queue.h" + +static void startWorker(Worker* worker); + +Worker* createMCWorker(struct Context* context, int id, Queue* queue) { + struct Worker* worker = new Worker(); + struct MCWorker* mcWorker = new MCWorker(); + worker->worker = (union Data*)mcWorker; + worker->tasks = queue; + mcWorker->id = id; + mcWorker->loopCounter = 0; + worker->taskReceive = C_taskReceiveMCWorker; + worker->shutdown = C_shutdownMCWorker; + pthread_create(&worker->thread, NULL, (void*)&startWorker, worker); + return worker; +} + +static void startWorker(struct Worker* worker) { + struct MCWorker* mcWorker = &worker->worker->MCWorker; + mcWorker->context = NEW(struct Context); + initContext(mcWorker->context); + Gearef(mcWorker->context, Worker)->worker = (union Data*)worker; + Gearef(mcWorker->context, Worker)->tasks = worker->tasks; + goto meta(mcWorker->context, worker->taskReceive); +} + +__code taskReceiveMCWorker(struct MCWorker* worker, struct Queue* tasks) { + goto tasks->take(getTaskMCWorker); +} + +__code getTaskMCWorker(struct MCWorker* mcWorker, struct Context* task, struct Worker* worker) { + if (!task) { + goto worker->shutdown(); // end thread + } + task->worker = worker; + enum Code taskCg = task->next; + task->next = C_odgCommitMCWorker; // commit outputDG after task exec + goto meta(task, taskCg); // switch task context +} + +__code getTaskMCWorker_stub(struct Context* context) { + MCWorker* mcWorker = (MCWorker*)GearImpl(context, Worker, worker); + Worker* worker = &Gearef(context,Worker)->worker->Worker; + struct Context* task = &Gearef(context, Queue)->data->Context; + goto getTaskMCWorker(context, mcWorker, task, worker); +} + +__code odgCommitMCWorker(struct MCWorker* worker, struct Context* task) { + if (task->iterate) { + struct Iterator* iterator = task->iterator; + goto iterator->barrier(task, odgCommitMCWorker1, odgCommitMCWorker6); + } else { + goto odgCommitMCWorker1(); + } +} + +__code odgCommitMCWorker_stub(struct Context* context) { + // switch worker context + struct Context* workerContext = context->worker->worker->MCWorker.context; + Gearef(workerContext, Worker)->worker = (union Data*)context->worker; + Gearef(workerContext, Worker)->task = context; + MCWorker* mcWorker = (MCWorker*)GearImpl(workerContext, Worker, worker); + goto odgCommitMCWorker(workerContext, + mcWorker, + context); +} + +__code odgCommitMCWorker1(struct MCWorker* worker, struct Context* task) { + int i = worker->loopCounter; + if (task->odg+i < task->maxOdg) { + goto odgCommitMCWorker2(); + } + worker->loopCounter = 0; + struct TaskManager* taskManager = task->taskManager; + goto taskManager->decrementTaskCount(odgCommitMCWorker6); +} + +__code odgCommitMCWorker2(struct MCWorker* worker, struct Context* task) { + int i = worker->loopCounter; + struct Queue* queue = GET_WAIT_LIST(task->data[task->odg+i]); + goto queue->isEmpty(odgCommitMCWorker3, odgCommitMCWorker5); +} + +__code odgCommitMCWorker3(struct MCWorker* worker, struct Context* task) { + int i = worker->loopCounter; + struct Queue* queue = GET_WAIT_LIST(task->data[task->odg+i]); + goto queue->take(odgCommitMCWorker4); +} + +__code odgCommitMCWorker4(struct MCWorker* worker, struct Context* task, struct Context* waitTask) { + 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, odgCommitMCWorker2); + } + goto odgCommitMCWorker2(); +} + +__code odgCommitMCWorker4_stub(struct Context* context) { + MCWorker* mcWorker = (MCWorker*)GearImpl(context, Worker, worker); + struct Context* task = Gearef(context, Worker)->task; + struct Context* waitTask = &Gearef(context, Queue)->data->Context; + goto odgCommitMCWorker4(context, + mcWorker, + task, + waitTask); +} + +__code odgCommitMCWorker5(struct MCWorker* worker, struct Context* task) { + worker->loopCounter++; + goto odgCommitMCWorker1(); +} + +__code odgCommitMCWorker6(struct MCWorker* worker, struct Context* task) { + struct Worker* taskWorker = task->worker; + goto taskWorker->taskReceive(taskWorker->tasks); +} + +__code shutdownMCWorker(struct MCWorker* worker) { + goto exit_code(); +} diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/SingleLinkedQueue.cbc --- a/src/parallel_execution/SingleLinkedQueue.cbc Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/SingleLinkedQueue.cbc Sun Jan 24 15:52:40 2021 +0900 @@ -10,10 +10,6 @@ queue->queue = (union Data*)singleLinkedQueue; singleLinkedQueue->top = new Element(); singleLinkedQueue->last = singleLinkedQueue->top; - queue->take = C_takeSingleLinkedQueue; - queue->put = C_putSingleLinkedQueue; - queue->isEmpty = C_isEmptySingleLinkedQueue; - queue->clear = C_clearSingleLinkedQueue; return queue; } diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/examples/DPP/PhilsImpl.cbc --- a/src/parallel_execution/examples/DPP/PhilsImpl.cbc Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/examples/DPP/PhilsImpl.cbc Sun Jan 24 15:52:40 2021 +0900 @@ -15,7 +15,7 @@ // } PhilsImpl; // ---- -Phils *createPhilsImpl(struct Context *context, int id, AtomicT right, AtomicT left){ +Phils* createPhilsImpl(struct Context *context, int id, AtomicT right, AtomicT left){ struct Phils* phils = new Phils(); struct PhilsImpl* phils_impl = new PhilsImpl(); phils->phils = (union Data *)phils_impl; diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/examples/DPP2/PhilsImpl.cbc --- a/src/parallel_execution/examples/DPP2/PhilsImpl.cbc Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/examples/DPP2/PhilsImpl.cbc Sun Jan 24 15:52:40 2021 +0900 @@ -35,12 +35,12 @@ __code putdown_rfork(struct PhilsImpl* phils, __code next(...)) { struct AtomicT_int* right_fork = phils->Rightfork; - goto right_fork->set(0, putdown_lfork); + goto right_fork->set(-1, putdown_lfork); } __code putdown_lfork(struct PhilsImpl* phils, __code next(...)) { struct AtomicT_int* left_fork = phils->Leftfork; - goto left_fork->set(0, thinking); + goto left_fork->set(-1, thinking); } @@ -51,12 +51,12 @@ __code pickup_rfork(struct PhilsImpl* phils, __code next(...)) { struct AtomicT_int* right_fork = phils->Rightfork; - goto right_fork->checkAndSet(-1, 0, pickup_lfork, pickup_rfork); + goto right_fork->checkAndSet(-1, phils->self, pickup_lfork, pickup_rfork); } __code pickup_lfork(struct PhilsImpl* phils, __code next(...)) { struct AtomicT_int* left_fork = phils->Leftfork; - goto left_fork->checkAndSet(-1, 0, pickup_rfork, eating); + goto left_fork->checkAndSet(-1, phils->self, pickup_rfork, eating); } diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/generate_context.pl --- a/src/parallel_execution/generate_context.pl Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/generate_context.pl Sun Jan 24 15:52:40 2021 +0900 @@ -121,8 +121,21 @@ my ($typed_variable, $generics) = parsed_generics_from_tree($tree); my ($type_var, $type_ins) = check_use_generics($typed_variable, $generics, $gears->{generics_list}); - convertGenerics($type_var, $type_ins); + my $modify_list = convertGenerics($type_var, $type_ins); + my @mod; + if (%$modify_list) { + for my $ftype (qw/cbc header/) { + for my $fname (keys %{$modify_list->{$ftype}}) { + my $fileInfo = $modify_list->{$ftype}->{$fname}; + for my $item (grep { $_->{before_impl} } @{$fileInfo}) { + print STDERR "@{$item->{before_impl}}\n"; + } + } + } + } + + #p @mod; $gears->tree2create_context_h($tree); } @@ -535,11 +548,13 @@ my $replaceType = $type; my $replaceImpls = $impl; + my $targetImpl = $impl; $replaceType =~ s/$type/${type}_$defType/; my $repimpl = 0; if (defined $typed_variables->{$impl}) { $replaceImpls =~ s/$type/${type}_$defType/; + $targetImpl =~ s/$type/${type}_$defType/; $replaceImpls =~ s/$/_$defType/; $repimpl = 1; } @@ -555,7 +570,13 @@ if ($impl eq $replaceImpls) { #not impl push(@{$modifyList->{cbc}->{$file}},{before => [$type], after => [$replaceType]}); } else { #impl - push(@{$modifyList->{cbc}->{$file}},{before => [$type, $impl], after => [$replaceType, $replaceImpls]}); + #push(@{$modifyList->{cbc}->{$file}},{before => [$type, $impl], after => [$replaceType, $replaceImpls]}); + push(@{$modifyList->{cbc}->{$file}}, + { + before => [$type], after => [$replaceType], + before_impl => [$impl], after_impl => [$replaceImpls] + } + ); } my @cbc_cont; @@ -564,7 +585,7 @@ while (my $line = <$fh> ){ $line =~ s/$type(<.*>)?/$replaceType/g; if ($repimpl) { - $line =~ s/$impl(<.*>)?/$replaceImpls/g; + $line =~ s/${targetImpl}(<.*>)?/$replaceImpls/g; } $line =~ s/${type_v}([\s\*])/$defType$1/; push(@cbc_cont, $line); @@ -576,9 +597,6 @@ } } - #p $modifyList; - - #p $typed_variables; # for my $type (keys %$typed_variables) { # #my @cfiles = grep { /\.c$/ } keys %{$typed_variables->{$type}->{_caller}}; @@ -594,6 +612,7 @@ # } # close $fh; #} + return $modifyList; } diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/generate_stub.pl --- a/src/parallel_execution/generate_stub.pl Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/generate_stub.pl Sun Jan 24 15:52:40 2021 +0900 @@ -78,6 +78,7 @@ my $generateHaveOutputStub = { counter => undef, list => undef }; my $replaceCodeGearNames = {}; my $isGmain; +my $constructorInfo = {}; # this for statement is main routine @@ -89,6 +90,9 @@ $cbc_content = Gears::Stub->generate_new_main(cbc_path => $fn, cbc_content => $cbc_content); getDataGear($fn, $cbc_content); } + if (%$constructorInfo) { #replace constructor + $cbc_content = Gears::Stub->replaceConstructor($constructorInfo, $implInterfaceInfo, $cbc_content); + } generateDataGear($fn, $cbc_content); } @@ -164,6 +168,7 @@ &getDataGear($cbc_source_path,slurpCbCFiles($cbc_source_path)); } $implInterfaceInfo->{genConstructor} = 0; + $constructorInfo = Gears::Stub->parsedConstructor(\@content); } elsif(/^(.*)par goto (\w+)\((.*)\)/) { debug_print("getDataGear",__LINE__, $_) if $opt_debug; my $codeGearName = $2; diff -r e2a0e5a65a3d -r 5125f75dd6f2 src/parallel_execution/lib/Gears/Stub.pm --- a/src/parallel_execution/lib/Gears/Stub.pm Sat Jan 23 21:02:49 2021 +0900 +++ b/src/parallel_execution/lib/Gears/Stub.pm Sun Jan 24 15:52:40 2021 +0900 @@ -162,5 +162,64 @@ $s; } +sub parsedConstructor { + my ($class, $lines) = @_; + my $inConst = undef; + my $info = {}; + + for my $line (@$lines) { + next unless $line; + #Queue* createSingleLinkedQueue(struct Context* context) { + if ($line =~ /(\w+)\*?\s+create(\w+)\(/) { + $inConst = 1; + } + + next unless ($inConst); + + if ($line =~ /(\w+)\-\>(\w+)\s*=\s*(\w+)/) { + $info->{$1}->{$2} = $3; + } + + if ($line =~ /^}/) { + $inConst = 0; + } + } + + return $info; +} + +sub replaceConstructor { + my ($class, $constructorInfo, $implInterfaceInfo, $cbc_content) = @_; + my $interfaceName = lcfirst($implInterfaceInfo->{interface}); + my @constructorCodeGears = keys %{$constructorInfo->{$interfaceName}}; + my @interfaceCodeGears = keys %{$implInterfaceInfo->{parsedInterfaceInfo}->{codeName}}; + + #generate interface->method = C_method + if ($implInterfaceInfo->{genConstructor}) { + #constructor declaration is perfect + return $cbc_content; + } + return $cbc_content; + + #for my $codeGear (keys $constructorInfo->{$interfaceName}) { + #} + + #p $constructorInfo; + #p $implInterfaceInfo; + ## replace interface->method = method --> interface->method = C_methodImpl + #my @aaa = grep { exists $implInterfaceInfo->{parsedInterfaceInfo}->{$_} } @constructorCodeGears; + ##if ((scalar(@constructorCodeGears) == scalar(@interfaceCodeGears)) || $implInterfaceInfo->{genConstructor}) { + + + ## generate interface->method = C_methodImpl + #my %wantMethods = map { $_ => 0 } @interfaceCodeGears; + #for (@constructorCodeGears) { + # $wantMethods{$_} = 1; #find + #} + #my @generateMethods = grep { $wantMethods{$_} == 0 } @interfaceCodeGears; + ##p @generateMethods; + return $cbc_content; +} + 1;