changeset 359:e68080586c15

merge 357 358
author Nozomi Teruya <e125769@ie.u-ryukyu.ac.jp>
date Sat, 24 Jun 2017 20:11:48 +0900
parents 98c6e13d8ec7 (current diff) 4ae1eebccbd1 (diff)
children ba5959d7901d
files src/parallel_execution/CMakeLists.txt src/parallel_execution/context.h
diffstat 12 files changed, 224 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/src/parallel_execution/CMakeLists.txt	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/CMakeLists.txt	Sat Jun 24 20:11:48 2017 +0900
@@ -67,7 +67,7 @@
   TARGET
       calc
   SOURCES 
-      examples/calc.cbc examples/Add.cbc examples/Mult.cbc examples/calc.cbc SingleLinkedStack.cbc CPUWorker.cbc time.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc SemaphoreImpl.cbc
+      examples/calc.cbc examples/Add.cbc examples/Mult.cbc examples/InitIntegerDataGears.cbc CPUWorker.cbc time.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc SemaphoreImpl.cbc
 )
 
 if (${USE_CUDA})
--- a/src/parallel_execution/SemaphoreImpl.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/SemaphoreImpl.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -34,4 +34,3 @@
     pthread_mutex_unlock(&semaphore->mutex);
     goto next(...);
 }
-
--- a/src/parallel_execution/Stack.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/Stack.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -1,14 +1,14 @@
-typedef struct Stack<Impl>{
-        union Data* stack;
-        union Data* data;
-        union Data* data1;
+typedef struct Stack<Type, Impl>{
+        Type* stack;
+        Type* data;
+        Type* data1;
         __code whenEmpty(...);
         __code clear(Impl* stack,__code next(...));
-        __code push(Impl* stack,union Data* data, __code next(...));
-        __code pop(Impl* stack, __code next(union Data*, ...));
-        __code pop2(Impl* stack, union Data** data, union Data** data1, __code next(union Data**, union Data**, ...));
+        __code push(Impl* stack,Type* data, __code next(...));
+        __code pop(Impl* stack, __code next(Type* data, ...));
+        __code pop2(Impl* stack, Type** data, Type** data1, __code next(Type** data, Type** data1, ...));
         __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
-        __code get(Impl* stack, union Data** data, __code next(...));
+        __code get(Impl* stack, Type** data, __code next(...));
         __code get2(Impl* stack,..., __code next(...));
         __code next(...);
 } Stack;
--- a/src/parallel_execution/TaskManager.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/TaskManager.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -2,7 +2,7 @@
     union Data* taskManager;
     __code createTask(struct TaskManager* taskManager);
     __code spawn(Impl* taskManager, struct Queue* queue, struct Context* task, __code next(...));
-    __code setWaitTask(struct Queue* queue, struct Context* task, __code next(...));
+    __code spawnTasks(struct TaskManager* taskManager, Impl* taskManagerImpl, struct Context* contexts);
     __code shutdown(struct LoopCounter* loopCounter, struct TaskManager* taskManager, Impl* taskManagerImpl, struct Queue* queue, __code next(...));
     __code next(...);
     __code task(...);
--- a/src/parallel_execution/TaskManagerImpl.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/TaskManagerImpl.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -13,14 +13,15 @@
     taskManager->gpu = numIO;
     taskManager->cpu = numIO+numGPU;
     taskManager->maxCPU = numIO+numGPU+numCPU;
-    taskManager->createTask = C_createTask;
+    taskManager->spawnTasks = C_spawnTasksTaskManager;
     taskManager->spawn = C_spawnTaskManager;
-    taskManager->setWaitTask = C_setWaitTask;
     taskManager->shutdown  = C_shutdownTaskManager;
     struct TaskManagerImpl* taskManagerImpl = new TaskManagerImpl();
     taskManagerImpl -> activeQueue = createSingleLinkedQueue(context);
     taskManagerImpl -> taskQueue = createSingleLinkedQueue(context);
     taskManagerImpl -> numWorker = taskManager->maxCPU;
+    taskManagerImpl -> loopCounter = new LoopCounter();
+    taskManagerImpl -> loopCounter -> i = 0;
     createWorkers(context, taskManager, taskManagerImpl);
     taskManager->taskManager = (union Data*)taskManagerImpl;
     return taskManager;
@@ -52,28 +53,63 @@
     }
 }
 
-__code createTask(struct TaskManager* taskManager) {
-    taskManager->context = NEW(struct Context);
-    initContext(taskManager->context);
-    taskManager->context->taskManager = (struct TaskManager*)taskManager->taskManager;
-    taskManager->context->idg = taskManager->context->dataNum;
-    goto meta(context, C_setWorker);
+__code spawnTasksTaskManager(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** contexts) {
+    int i = taskManagerImpl->loopCounter->i;
+    struct Context* task = contexts[i];
+    if(i < GET_SIZE(contexts)) {
+        taskManagerImpl->loopCounter->i++;
+        taskManager->context = task;
+        taskManager->next = C_spawnTasksTaskManager;
+        goto meta(context, C_setWorker);
+    }
+    taskManagerImpl->loopCounter->i = 0;
+    goto meta(context, C_spawnTasksTaskManager1);
+}
+
+__code spawnTasksTaskManager_stub(struct Context* context) {
+    TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
+    goto spawnTasksTaskManager(context,
+                               Gearef(context, TaskManager),
+                               taskManager,
+                               Gearef(context, TaskManager)->contexts);
 }
 
-__code setWorker(struct TaskManagerImpl* taskManager, struct Context* task, __code next(...)) {
+__code spawnTasksTaskManager1(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** contexts, __code next(...)) {
+    int i = taskManagerImpl->loopCounter->i;
+    struct Context* task = contexts[i];
+    if(i < GET_SIZE(contexts)) {
+        taskManagerImpl->loopCounter->i++;
+        taskManager->context = task;
+        taskManager->next = C_spawnTasksTaskManager1;
+        goto meta(context, C_spawnTaskManager);
+    }
+    taskManagerImpl->loopCounter->i = 0;
+    goto meta(context, next);
+}
+
+__code spawnTasksTaskManager1_stub(struct Context* context) {
+    TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
+    goto spawnTasksTaskManager1(context,
+                               Gearef(context, TaskManager),
+                               taskManager,
+                               Gearef(context, TaskManager)->contexts,
+                               Gearef(context, TaskManager)->next1);
+}
+
+__code setWorker(struct TaskManagerImpl* taskManager, struct Context* task) {
     task->workerId = taskManager->sendWorkerIndex;
     if(++taskManager->sendWorkerIndex >= taskManager->numWorker) {
         taskManager->sendWorkerIndex = 0;
     }
-    goto next(...);
+    goto meta(context, C_setWaitTask);
 }
 
 __code setWorker_stub(struct Context* context) {
     TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
-    goto setWorker(context, taskManager, Gearef(context, TaskManager)->context, Gearef(context, TaskManager)->next);
+    goto setWorker(context, taskManager, Gearef(context, TaskManager)->context);
 }
 
-__code setWaitTask(struct TaskManager* taskManager, struct Queue* queue, struct Context* task, struct LoopCounter* loopCounter, __code next(...)) {
+__code setWaitTask(struct Queue* queue, struct Context* task, struct LoopCounter* loopCounter, __code next(...)) {
     int i = loopCounter->i;
     if(task->idg + i < task->maxIdg) {
         loopCounter->i++;
@@ -82,16 +118,16 @@
         queue->data = (Data *)task;
         goto meta(context, queue->queue->Queue.put);
     }
-    goto meta(context, taskManager->taskManager->TaskManager.spawn);
+    loopCounter->i = 0;
+    goto next(...);
 }
 
 __code setWaitTask_stub(struct Context* context) {
-    TaskManager* taskManager = Gearef(context, TaskManager);
     struct Context* task = Gearef(context, TaskManager)->context;
-    goto setWaitTask(context, taskManager, Gearef(context, Queue), task, Gearef(task, LoopCounter), Gearef(context, TaskManager)->next);
+    goto setWaitTask(context, Gearef(context, Queue), task, Gearef(task, LoopCounter), Gearef(context, TaskManager)->next);
 }
 
-__code spawnTaskManager(struct TaskManagerImpl* taskManager, struct Queue* queue, struct Context* task, __code next(...)) {
+__code spawnTaskManager(struct TaskManagerImpl* taskManager, struct Context* task, __code next(...)) {
     if (task->idgCount == 0) {
         goto meta(context, C_taskSend);
     } else {
@@ -105,7 +141,6 @@
     pthread_mutex_lock(&taskManager->mutex);
     goto spawnTaskManager(context,
             taskManager,
-            Gearef(context, Queue),
             Gearef(context, TaskManager)->context,
             Gearef(context, TaskManager)->next);
 }
@@ -121,7 +156,10 @@
 
 __code taskSend_stub(struct Context* context) {
     TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
-    goto taskSend(context, taskManager, Gearef(context, Queue), Gearef(context, TaskManager)->context, Gearef(context, TaskManager)->next);
+    goto taskSend(context,
+            taskManager, Gearef(context, Queue),
+            Gearef(context, TaskManager)->context,
+            Gearef(context, TaskManager)->next);
 }
 
 __code shutdownTaskManager(struct LoopCounter* loopCounter, struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Queue* queue, __code next(...)) {
--- a/src/parallel_execution/context.h	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/context.h	Sat Jun 24 20:11:48 2017 +0900
@@ -53,6 +53,7 @@
 
 #define GET_META(dseg) ((struct Meta*)(((void*)dseg) - sizeof(struct Meta)))
 #define GET_TYPE(dseg) (GET_META(dseg)->type)
+#define GET_SIZE(dseg) (GET_META(dseg)->size)
 #define GET_WAIT_LIST(dseg) (GET_META(dseg)->wait)
 
 #define Gearef(context, t) (&(context)->data[D_##t]->t)
@@ -109,25 +110,19 @@
     struct LoopCounter {
         int i;
     } LoopCounter;
-    struct CodeGear {
-        union Data* CodeGear;
-        enum Code code;
-        union Data* dataGears[10];
-        enum Code next;
-    } CodeGear;
     struct TaskManager {
 #ifdef USE_CUDA_MAIN_THREAD
         volatile 
 #endif
         union Data* taskManager;
-        enum Code createTask; // create NEW  contexts for execution & argument
         enum Code spawn;      // start NEW context on the worker
-        enum Code setWaitTask;
+        enum Code spawnTasks; // start NEW contexts on the worker
         enum Code shutdown;
-
         enum Code next;
+        enum Code next1;
         enum Code task;
         struct Context* context;
+        struct Context** contexts;
         union Data* data;
         int worker;
         int cpu;
@@ -142,6 +137,7 @@
         struct Queue* activeQueue;
         struct Queue* taskQueue;
         struct Worker** workers;
+        struct LoopCounter* loopCounter;
     } TaskManagerImpl;
     struct Worker {
         union Data* worker;
--- a/src/parallel_execution/examples/Add.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/examples/Add.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -1,7 +1,7 @@
 #include "../../context.h"
 #include <stdio.h>
 __code add(struct Integer* input1, struct Integer* input2, __code next(struct Integer* output, ...)) {
-    struct Integer* output = NULL;
+    struct Integer* output = *O_output;
     output->value = input1->value + input2->value;
     printf("%d + %d = %d\n", input1->value, input2->value, output->value);
     *O_output = output;
--- a/src/parallel_execution/examples/Mult.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/examples/Mult.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -1,9 +1,9 @@
 #include "../../context.h"
 #include <stdio.h>
 __code mult(struct Integer* input1, struct Integer* input2, __code next(struct Integer* output, ...)) {
-    struct Integer* output = NULL;
+    struct Integer* output = *O_output;
     output->value = input1->value * input2->value;
-    printf("%d + %d = %d\n", input1->value, input2->value, output->value);
+    printf("%d * %d = %d\n", input1->value, input2->value, output->value);
     *O_output = output;
     goto meta(context, next);
 }
--- a/src/parallel_execution/examples/calc.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/examples/calc.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -100,13 +100,17 @@
 
     loopCounter->i = 0;
     taskManager->next = C_code1;
+    sleep(5);
     goto meta(context, taskManager->taskManager->TaskManager.shutdown);
 }
 
-__code createTask2(LoopCounter* loopCounter, TaskManager* taskManager, Integer *integer1, Integer *integer2, Integer *integer3) {
-    int i = loopCounter->i;
-    integer1->value = i;
-    integer2->value = i+1;
+__code createTask2(struct LoopCounter* loopCounter, struct TaskManager* taskManager) {
+    struct Context** tasks = (struct Context**)ALLOC_ARRAY(context, Context, 3);
+
+    Integer* integer1 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
+    Integer* integer2 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
+    Integer* integer3 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
+    // par goto mult(integer1, integer2, integer3, __exit);
     struct Context* task = NEW(struct Context);
     initContext(task);
     task->taskManager = &taskManager->taskManager->TaskManager;
@@ -119,54 +123,45 @@
     task->odg = task->maxIdg;
     task->data[task->odg] = (union Data*)integer3;
     task->maxOdg = task->odg + 1;
-    taskManager->context = task;
-    taskManager->next = C_createTask3;
-    goto meta(context, taskManager->taskManager->TaskManager.setWaitTask);
-}
+    tasks[0] = task;
 
-__code createTask2_stub(struct Context* context) {
-    Integer* integer1 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    Integer* integer2 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    Integer* integer3 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    goto createTask2(context,
-            Gearef(context, LoopCounter),
-            Gearef(context, TaskManager),
-            integer1,
-            integer2,
-            integer3);
-}
-
-__code createTask3(LoopCounter* loopCounter, TaskManager* taskManager, Integer *integer1, Integer *integer2, Integer *integer3) {
-    int i = loopCounter->i;
-    integer1->value = i;
-    integer2->value = i+1;
-    struct Context* task = NEW(struct Context);
+    Integer* integer4 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
+    Integer* integer5 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
+    // par goto add(integer4, integer5, integer1, __exit);
+    task = NEW(struct Context);
     initContext(task);
     task->taskManager = &taskManager->taskManager->TaskManager;
     task->next = C_add;
     task->idgCount = 2;
     task->idg = task->dataNum;
-    task->data[task->idg] = (union Data*)integer1;
-    task->data[task->idg+1] = (union Data*)integer2;
+    task->data[task->idg] = (union Data*)integer4;
+    task->data[task->idg+1] = (union Data*)integer5;
     task->maxIdg = task->idg + 2;
     task->odg = task->maxIdg;
-    task->data[task->odg] = (union Data*)integer3;
+    task->data[task->odg] = (union Data*)integer1;
     task->maxOdg = task->odg + 1;
-    taskManager->context = task;
-    taskManager->next = C_createTask3;
-    goto meta(context, taskManager->taskManager->TaskManager.setWaitTask);
-}
+    tasks[1] = task;
 
-__code createTask3_stub(struct Context* context) {
-    Integer* integer1 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    Integer* integer2 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    Integer* integer3 = &ALLOCATE_DATA_GEAR(context, Integer)->Integer;
-    goto createTask3(context,
-            Gearef(context, LoopCounter),
-            Gearef(context, TaskManager),
-            integer1,
-            integer2,
-            integer3);
+    // par goto initIntegerDataGears(integer2, integer4, integer5, __exit);
+    task = NEW(struct Context);
+    initContext(task);
+    task->taskManager = &taskManager->taskManager->TaskManager;
+    task->next = C_initIntegerDataGears;
+    task->idgCount = 0;
+    task->idg = task->dataNum;
+    task->maxIdg = task->idg;
+    task->odg = task->maxIdg;
+    task->data[task->odg] = (union Data*)integer2;
+    task->data[task->odg+1] = (union Data*)integer4;
+    task->data[task->odg+2] = (union Data*)integer5;
+    task->maxOdg = task->odg + 3;
+    tasks[2] = task;
+
+    //goto taskManager->setWaitTask(createTask1);
+    taskManager->contexts = tasks;
+    // goto crateTask1();
+    taskManager->next1 = C_createTask1;
+    goto meta(context, taskManager->taskManager->TaskManager.spawnTasks);
 }
 
 void init(int argc, char** argv) {
--- a/src/parallel_execution/generate_context.pl	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/generate_context.pl	Sat Jun 24 20:11:48 2017 +0900
@@ -108,6 +108,7 @@
         if (/struct (\w+) \{/) {
             $dataGear{$1} = $1;
         }
+        $dataGear{"Context"} = "Context";
     }
 }
 
@@ -159,7 +160,7 @@
     // context->data[D_ActiveQueue] = createSynchronizedQueue(context);
     // context->data[D_WaitQueue]   = createSynchronizedQueue(context);
 
-    context->dataNum = D_Queue;
+    context->dataNum = D_Worker;
 }
 EOFEOF
 
--- a/src/parallel_execution/generate_stub.pl	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/generate_stub.pl	Sat Jun 24 20:11:48 2017 +0900
@@ -38,21 +38,59 @@
 my %outputArgs;      # continuation's output variables
 my %dataGear;
 my %dataGearName;
+my %generic;
+my %dataGearVarType;
 my $implementation;
 my $interface;
 
+# interface definision
+#
+# typedef struct Stack<Type, Impl>{
+#         Type* stack;
+#         Type* data;
+#         Type* data1;
+#         __code whenEmpty(...);
+#         __code clear(Impl* stack,__code next(...));
+#         __code push(Impl* stack,Type* data, __code next(...));
+#         __code pop(Impl* stack, __code next(Type*, ...));
+#         __code pop2(Impl* stack, Type** data, Type** data1, __code next(Type**, Type**, ...));
+#         __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
+#         __code get(Impl* stack, Type** data, __code next(...));
+#         __code get2(Impl* stack,..., __code next(...));
+#         __code next(...);
+# } Stack;
+#
+# calling example
+#
+# goto nodeStack->push((union Data*)node, stackTest3);
+#
+# generated meta level code
+#
+# Gearef(context, Stack)->stack = nodeStack->stack;
+# Gearef(context, Stack)->data = (union Data*)node;
+# Gearef(context, Stack)->next = C_stackTest3;
+# goto meta(context, nodeStack->push);
+
 sub getDataGear {
     my ($filename) = @_;
     my ($codeGearName, $name, $inTypedef);
     open my $fd,"<",$filename or die("can't open $filename $!");
     while (<$fd>) {
         if (! $inTypedef) {
-            if (/^typedef struct (\w+)/) {
+            if (/^typedef struct (\w+)\s*<(.*)>/) {
                 $inTypedef = 1;
                 $name = $1;
                 $dataGear{$name} = $_;
                 $var{$name} = {};
                 $code{$name} = {};
+                $generic{$name} = \split(/,/,$2);
+            } elsif (/^typedef struct (\w+)/) {
+                $inTypedef = 1;
+                $name = $1;
+                $dataGear{$name} = $_;
+                $var{$name} = {};
+                $code{$name} = {};
+                $generic{$name} = [];
             } elsif (/^(\w+)(\*)+ create(\w+)\(/) {
                 if (defined $interface) {
                    die "duplicate interface $interface\n"; 
@@ -74,8 +112,29 @@
                 $ttype = $2;
             }
             $var{$name}->{$tname} = $ttype;
-	} elsif (/\_\_code (\w+)\(/) {
-            $code{$name}->{$1} = 1;
+        } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) {
+            my $args = $2;
+            my $method = $1;
+            $code{$name}->{$method} = [];
+            while($args) {
+                if ($args =~ s/(^\s*,\s*)//) {
+                }
+                # continuation case
+                if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) {
+                    my $next = $2;
+                    my @args = split(/,/,$3);
+                    push(@{$code{$name}->{$method}},$next); 
+                } elsif ($args =~ s/^(struct|union) (\w+)(\*)+\s(\w+)//) {
+                    my $structType = $1;
+                    my $typeName = $2;
+                    my $varName = $4;
+                    my $typeField = lcfirst($typeName);
+                    push(@{$code{$name}->{$method}},$varName); 
+                } elsif ($args =~ s/(.*,)//) {
+                } else {
+                    last;
+                }
+            }
         }
         if (/^}/) {
             $inTypedef = 0;
@@ -99,6 +158,7 @@
         return 0 if ( $n eq $varname1);
     }
     push @{$dataGearVar{$codeGearName}}, $varname1;
+    push @{$dataGearVarType{$codeGearName}}, $typeName;
     if ($typeName eq $implementation) {
         # get implementation
         $dataGearName{$codeGearName} .= "\t$typeName* $varName = ($typeName*)GearImpl(context, $interface, $varName);\n";
@@ -253,6 +313,31 @@
                     print $fd $outputVar{$codeGearName};
                 }
                 next;
+            } elsif (/^(.*)goto (\w+)\-\>(\w+)\((.*)\);/) {
+                # handling goto statement  
+                # convert it to the meta call form with two arugments, that is context and enum Code
+                my $prev = $1;
+                my $next = $2;
+                my $method = $3;
+                my @args = split(/,/,$4);
+                my @types = @{$dataGearVarType{$codeGearName}};
+                my $ntype;
+                for my $v (@{$dataGearVar{$codeGearName}}) {
+                    my $t = shift @types;
+                    if ($v eq $next) {
+                        $ntype = $t;
+                    }
+                }
+                print $fd "\tGearef(context, $ntype)->$next = $next->$next;\n";
+                # Put interface argument 
+                my $prot = $code{$ntype}->{$method};
+                for my $arg (@args) {
+                    my $p = shift @$prot;
+                    next if ($p eq $arg);
+                    print $fd "\tGearef(context, $ntype)->$p = $arg;\n";
+                }
+                print $fd "${prev}goto meta(context, $next->$next->$ntype.$method);\n";
+                next;
             } elsif (/^(.*)goto (\w+)\((.*)\);/) {
                 # handling goto statement  
                 # convert it to the meta call form with two arugments, that is context and enum Code
--- a/src/parallel_execution/test/stack_test.cbc	Sat Jun 24 20:07:27 2017 +0900
+++ b/src/parallel_execution/test/stack_test.cbc	Sat Jun 24 20:11:48 2017 +0900
@@ -5,46 +5,44 @@
     stack->stack = (union Data*)createSingleLinkedStack(context);
     Node* node = new Node();
     node->color = Red;
-    stack->data = (union Data*)node;
-    stack->next = C_assert1;
-    goto meta(context, stack->stack->Stack.push);
-}
-
-__code assert1(struct Stack* stack) {
-    SingleLinkedStack* singleLinkedStack = &stack->stack->Stack.stack->SingleLinkedStack;
-    assert(singleLinkedStack->top->data->Node.color == Red);
-    goto meta(context, C_stackTest2);
+    goto stack->push(node, stackTest2);
 }
 
 __code stackTest2(struct Stack* stack) {
     Node* node = new Node();
     node->color = Black;
-    stack->data = (union Data*)node;
-    stack->next = C_assert2;
-    goto meta(context, stack->stack->Stack.push);
+    goto stack->push(node, stackTest3);
 }
 
-__code assert2(struct Stack* stack) {
+__code stackTest2_stub(struct Context* context) {
     SingleLinkedStack* singleLinkedStack = &stack->stack->Stack.stack->SingleLinkedStack;
-    assert(singleLinkedStack->top->data->Node.color == Black);
-    goto meta(context, C_stackTest3);
+    assert(singleLinkedStack->top->data->Node.color == Red);
+    Stack* stack = Gearef(context, Stack);
+    goto stackTest2(context, stack);
 }
 
 __code stackTest3(struct Stack* stack) {
-    stack->next = C_assert3;
-    goto meta(context, stack->stack->Stack.pop);
+    goto stack->pop(assert3);
 }
 
-
-__code assert3(struct Stack* stack) {
+__code stackTest3_stub(struct Context* context) {
+    /*
+        assert on stack implementation
+    */
     SingleLinkedStack* singleLinkedStack = &stack->stack->Stack.stack->SingleLinkedStack;
-    assert(singleLinkedStack->top->data->Node.color == Red);
-    goto meta(context, C_exit_code);
+    assert(singleLinkedStack->top->data->Node.color == Black);
+    Stack* stack = Gearef(context, Stack);
+    goto stackTest3(context, stack);
+} 
+
+__code assert3(struct Node* node, struct Stack* stack) {
+    /*
+        assert in normal level
+    */
+    assert(node->color == Red);
+    goto exit_code(0);
 }
 
 int main(int argc, char const* argv[]) {
-    struct Context* main_context = NEW(struct Context);
-    initContext(main_context);
-    main_context->next = C_stackTest1;
-    goto start_code(main_context);
+    goto stackTest1();
 }