changeset 444:0c024ea61601

Using cas interface but occurred warning
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Sun, 26 Nov 2017 04:26:44 +0900
parents ff2764cb5edb
children f02bd096af64 57132ef16009
files src/parallel_execution/Atomic.cbc src/parallel_execution/AtomicReference.cbc src/parallel_execution/CMakeLists.txt src/parallel_execution/SynchronizedQueue.cbc src/parallel_execution/context.h src/parallel_execution/generate_stub.pl
diffstat 6 files changed, 66 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/parallel_execution/Atomic.cbc	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/Atomic.cbc	Sun Nov 26 04:26:44 2017 +0900
@@ -1,6 +1,9 @@
-typedef struct Atomic<Type, Impl>{
+typedef struct Atomic<Impl>{
     union Data* atomic;
-    union Data* data;
-    __code checkAndSet(Impl* atomic, Type* data, __code next(...));
+    union Data** ptr;
+    union Data* oldData;
+    union Data* newData;
+    __code checkAndSet(Impl* atomic, union Data** ptr, union Data* oldData, union Data* newData, __code next(...), __code fail(...));
     __code next(...);
+    __code fail(...);
 } Atomic;
--- a/src/parallel_execution/AtomicReference.cbc	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/AtomicReference.cbc	Sun Nov 26 04:26:44 2017 +0900
@@ -2,22 +2,16 @@
 
 #include <stdio.h>
 
-/* 
- * Nonnon-blocking atomic of Paper: Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Atomic Algorithms(https://www.research.ibm.com/people/m/michael/podc-1996.pdf).
- */
-
-Atomic* createAtomicReference(struct Context* context, union Data* data) {
+Atomic* createAtomicReference(struct Context* context) {
     struct Atomic* atomic = new Atomic();
     struct AtomicReference* atomicReference = new AtomicReference();
-    atomicReference->data = data;
-    atomic->atomic = AtomicReference;
+    atomic->atomic = (union Data*)atomicReference;
     atomic->checkAndSet = C_checkAndSetAtomicReference;
     return atomic;
 }
 
-__code checkAndSetAtomicReference(struct AtomicReference* atomic, union Data* data, __code next(...), __code fail(...)) {
-    union Data* oldData = atomic->data;
-    if (__sync_bool_compare_and_swap(&atomic->data, oldData, data)) {
+__code checkAndSetAtomicReference(struct AtomicReference* atomic, union Data** ptr, union Data* oldData, union Data* newData, __code next(...), __code fail(...)) {
+    if (__sync_bool_compare_and_swap(ptr, oldData, newData)) {
         goto next(...);
     }
     goto fail(...);
--- a/src/parallel_execution/CMakeLists.txt	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/CMakeLists.txt	Sun Nov 26 04:26:44 2017 +0900
@@ -61,21 +61,21 @@
   TARGET
       twice
   SOURCES
-      examples/twice/main.cbc examples/twice/createArray.cbc examples/twice/twice.cbc examples/twice/printArray.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc TimeImpl.cbc MultiDimIterator.cbc
+      examples/twice/main.cbc examples/twice/createArray.cbc examples/twice/twice.cbc examples/twice/printArray.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc TimeImpl.cbc MultiDimIterator.cbc AtomicReference.cbc
 )
 
 GearsCommand(
   TARGET
       calc
   SOURCES
-      examples/calc/calc.cbc examples/calc/add.cbc examples/calc/mult.cbc examples/calc/initIntegerDataGears.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc
+      examples/calc/calc.cbc examples/calc/add.cbc examples/calc/mult.cbc examples/calc/initIntegerDataGears.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc AtomicReference.cbc
 )
 
 GearsCommand(
   TARGET
       bitonicSort
   SOURCES
-      examples/bitonicSort/bitonicSort.cbc examples/bitonicSort/bitonicSwap.cbc examples/bitonicSort/makeArray.cbc examples/bitonicSort/printArray.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc MultiDimIterator.cbc TimeImpl.cbc
+      examples/bitonicSort/bitonicSort.cbc examples/bitonicSort/bitonicSwap.cbc examples/bitonicSort/makeArray.cbc examples/bitonicSort/printArray.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc MultiDimIterator.cbc TimeImpl.cbc AtomicReference.cbc
 )
 
 if (${USE_CUDA})
@@ -83,7 +83,7 @@
       TARGET
           CUDAtwice
       SOURCES 
-          examples/twice/main.cbc examples/twice/twice.cbc examples/twice/CUDAtwice.cu examples/twice/createArray.cbc examples/twice/printArray.cbc CPUWorker.cbc TimeImpl.cbc examples/twice/twice.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc CUDAWorker.cbc cuda.c MultiDimIterator.cbc CUDAExecutor.cbc
+          examples/twice/main.cbc examples/twice/twice.cbc examples/twice/CUDAtwice.cu examples/twice/createArray.cbc examples/twice/printArray.cbc CPUWorker.cbc TimeImpl.cbc examples/twice/twice.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc CUDAWorker.cbc cuda.c MultiDimIterator.cbc CUDAExecutor.cbc AtomicReference.cbc
     )
     set_target_properties(CUDAtwice PROPERTIES COMPILE_FLAGS "-Wall -g -DUSE_CUDAWorker=1") # -DUSE_CUDA_MAIN_THREAD
 
@@ -91,7 +91,7 @@
       TARGET
           CUDAbitonicSort
       SOURCES 
-          examples/bitonicSort/bitonicSort.cbc examples/bitonicSort/bitonicSwap.cbc examples/bitonicSort/CUDAbitonicSwap.cu examples/bitonicSort/makeArray.cbc examples/bitonicSort/printArray.cbc CPUWorker.cbc CUDAWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc cuda.c MultiDimIterator.cbc TimeImpl.cbc CUDAExecutor.cbc
+          examples/bitonicSort/bitonicSort.cbc examples/bitonicSort/bitonicSwap.cbc examples/bitonicSort/CUDAbitonicSwap.cu examples/bitonicSort/makeArray.cbc examples/bitonicSort/printArray.cbc CPUWorker.cbc CUDAWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc cuda.c MultiDimIterator.cbc TimeImpl.cbc CUDAExecutor.cbc AtomicReference.cbc
     )
     set_target_properties(CUDAbitonicSort PROPERTIES COMPILE_FLAGS "-Wall -g -DUSE_CUDAWorker=1")
 endif()
@@ -114,7 +114,7 @@
   TARGET
       multiDimIterator_test
   SOURCES
-      test/multiDimIterator_test.cbc test/printIterator.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc MultiDimIterator.cbc TimeImpl.cbc
+      test/multiDimIterator_test.cbc test/printIterator.cbc CPUWorker.cbc TaskManagerImpl.cbc SingleLinkedQueue.cbc SynchronizedQueue.cbc MultiDimIterator.cbc TimeImpl.cbc AtomicReference.cbc
 )
 
 GearsCommand(
--- a/src/parallel_execution/SynchronizedQueue.cbc	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/SynchronizedQueue.cbc	Sun Nov 26 04:26:44 2017 +0900
@@ -12,6 +12,7 @@
     synchronizedQueue->top = new Element();
     synchronizedQueue->top->next = NULL;
     synchronizedQueue->last = synchronizedQueue->top;
+    synchronizedQueue->atomic = createAtomicReference(context);
     queue->queue = (union Data*)synchronizedQueue;
     queue->take  = C_takeSynchronizedQueue;
     queue->put  = C_putSynchronizedQueue;
@@ -22,11 +23,8 @@
 
 __code clearSynchronizedQueue(struct SynchronizedQueue* queue, __code next(...)) {
     struct Element* top = queue->top;
-    if (__sync_bool_compare_and_swap(&queue->top, top, NULL)) {
-        goto next(...);
-    } else {
-        goto meta(context, C_clearSynchronizedQueue);
-    }
+    struct Atomic* atomic = queue->atomic;
+    goto atomic->checkAndSet(&queue->top, top, NULL, next(...), clearSynchronizedQueue);
 }
 
 __code putSynchronizedQueue(struct SynchronizedQueue* queue, union Data* data, __code next(...)) {
@@ -39,14 +37,12 @@
         goto meta(context, C_putSynchronizedQueue);
     }
     if (nextElement == NULL) {
-        if (__sync_bool_compare_and_swap(&last->next, nextElement, element)) {
-            __sync_bool_compare_and_swap(&queue->last, last, element);
-            goto next(...);
-        }
+        struct Atomic* atomic = queue->atomic;
+        goto atomic->checkAndSet(&last->next, nextElement, element, next(...), putSynchronizedQueue);
     } else {
-        __sync_bool_compare_and_swap(&queue->last, last, nextElement);
+        struct Atomic* atomic = queue->atomic;
+        goto atomic->checkAndSet(&queue->last, last, nextElement, putSynchronizedQueue, putSynchronizedQueue);
     }
-    goto meta(context, C_putSynchronizedQueue);
 }
 
 __code takeSynchronizedQueue(struct SynchronizedQueue* queue, __code next(union Data* data, ...)) {
@@ -58,17 +54,32 @@
     }
     if (top == last) {
         if (nextElement != NULL) {
-          __sync_bool_compare_and_swap(&queue->last, last, nextElement);
+            struct Atomic* atomic = queue->atomic;
+            goto atomic->checkAndSet(&queue->last, last, nextElement, takeSynchronizedQueue, takeSynchronizedQueue);
         }
     } else {
-        if (__sync_bool_compare_and_swap(&queue->top, top, nextElement)) {
-            data = nextElement->data;
-            goto next(data, ...);
-        }
+        struct Atomic* atomic = queue->atomic;
+        goto atomic->checkAndSet(&queue->top, top, nextElement, takeSynchronizedQueue1, takeSynchronizedQueue);
     }
     goto meta(context, C_takeSynchronizedQueue);
 }
 
+__code takeSynchronizedQueue1(struct SynchronizedQueue* queue, __code next(union Data* data, ...), struct Element* nextElement) {
+    data = nextElement->data;
+    goto next(data, ...);
+}
+
+__code takeSynchronizedQueue1_stub(struct Context* context) {
+	SynchronizedQueue* queue = (SynchronizedQueue*)GearImpl(context, Queue, queue);
+	enum Code next = Gearef(context, Queue)->next;
+	Data** O_data = &Gearef(context, Queue)->data;
+	goto takeSynchronizedQueue1(context,
+                                queue,
+                                next,
+                                O_data,
+                                (struct Element*)Gearef(context, Atomic)->newData);
+}
+
 __code isEmptySynchronizedQueue(struct SynchronizedQueue* queue, __code next(...), __code whenEmpty(...)) {
     if (queue->top)
         goto next(...);
--- a/src/parallel_execution/context.h	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/context.h	Sun Nov 26 04:26:44 2017 +0900
@@ -232,6 +232,7 @@
     struct SynchronizedQueue {
         struct Element* top;
         struct Element* last;
+        struct Atomic* atomic;
     } SynchronizedQueue;
     // Stack Interface
     struct Stack {
@@ -303,13 +304,14 @@
     } Node;
     struct Atomic {
         union Data* atomic;
-        union Data* data;
+        union Data** ptr;
+        union Data* oldData;
+        union Data* newData;
         enum Code checkAndSet;
         enum Code next;
         enum Code fail;
     } Atomic;
     struct AtomicReference {
-        union Data* data;
     } AtomicReference;
     struct Semaphore {
         union Data* semaphore;
--- a/src/parallel_execution/generate_stub.pl	Tue Nov 21 09:28:27 2017 +0900
+++ b/src/parallel_execution/generate_stub.pl	Sun Nov 26 04:26:44 2017 +0900
@@ -281,6 +281,7 @@
     my $inMain = 0 ;
     my %stub;
     my $codeGearName;
+    my %localVarType;
 
     while (<$in>) {
         if (! $inTypedef && ! $inStub && ! $inMain) {
@@ -289,6 +290,7 @@
             } elsif (/^int main\((.*)\) {/) {
                 $inMain = 1;
             } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) {
+                %localVarType = {};
                 $codeGearName = $1;
                 my $args = $2;
                 my $tail = $3;
@@ -393,6 +395,10 @@
                         $ftype = lcfirst($ntype);
                     }
                 }
+                if (!defined $ntype) {
+                    $ntype = $localVarType{$next};
+                    $ftype = lcfirst($ntype);
+                }
                 print $fd "\tGearef(context, $ntype)->$ftype = (union Data*) $next;\n";
                 # Put interface argument
                 my $prot = $code{$ntype}->{$method};
@@ -407,7 +413,11 @@
                     $pName = $2;
                     $arg =~ s/^(\s)*(\w+)/$2/;
                     if ($pType =~ s/\_\_code$//) {
-                        print $fd "\tGearef(context, $ntype)->$pName = C_$arg;\n";
+                        if ($arg =~ /(\w+)\(.*\)/) {
+                            print $fd "\tGearef(context, $ntype)->$pName = $1;\n";
+                        } else {
+                            print $fd "\tGearef(context, $ntype)->$pName = C_$arg;\n";
+                        }
                     } elsif ($pType =~ s/Data$//){ 
                         print $fd "\tGearef(context, $ntype)->$pName = (union Data*) $arg;\n";
                     } else {
@@ -515,10 +525,15 @@
                     print $fd "${prev}goto meta(context, C_$next);\n";
                     next;
                 }
-            } elsif(/^}/) {
+            } elsif(/^.*(struct|union)?\s(\w+)\*\s(\w+)\s?[=;]/) {
+                my $type    = $2;
+                my $varName = $3;
+                $localVarType{$varName} = $type;
+                s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g;   # replacing new
+            }
+            elsif(/^}/) {
                 $inParGoto = 0;
-            }
-            else {
+            } else {
                 s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g;   # replacing new
             }
             # gather type name and type