changeset 441:5a737c3df91c

Add AtomicReference Implements of Atomic Interface
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Tue, 21 Nov 2017 04:28:36 +0900
parents 55db2a339958
children 481fce540daf
files src/parallel_execution/Atomic.cbc src/parallel_execution/AtomicReference.cbc src/parallel_execution/Executor.cbc src/parallel_execution/context.h src/parallel_execution/examples/twice/twice.cbc
diffstat 5 files changed, 44 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/Atomic.cbc	Tue Nov 21 04:28:36 2017 +0900
@@ -0,0 +1,6 @@
+typedef struct Atomic<Type, Impl>{
+    Type* atomic;
+    Type* data;
+    __code checkAndSet(Impl* atomic, Type* data, __code next(...));
+    __code next(...);
+} Atomic;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/AtomicReference.cbc	Tue Nov 21 04:28:36 2017 +0900
@@ -0,0 +1,24 @@
+#include "../context.h"
+
+#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) {
+    struct Atomic* atomic = new Atomic();
+    struct AtomicReference* atomicReference = new AtomicReference();
+    atomicReference->data = data;
+    atomic->atomic = 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)) {
+        goto next(...);
+    }
+    goto fail(...);
+}
--- a/src/parallel_execution/Executor.cbc	Mon Nov 06 19:04:41 2017 +0900
+++ b/src/parallel_execution/Executor.cbc	Tue Nov 21 04:28:36 2017 +0900
@@ -1,5 +1,5 @@
-typedef struct Executor<Impl>{
-    union Data* Executor;
+typedef struct Executor<Type, Impl>{
+    Type* Executor;
     struct Context* task;
     __code read(Impl* executor, struct Context* task, __code next(...));
     __code exec(Impl* executor, struct Context* task, __code next(...));
--- a/src/parallel_execution/context.h	Mon Nov 06 19:04:41 2017 +0900
+++ b/src/parallel_execution/context.h	Tue Nov 21 04:28:36 2017 +0900
@@ -128,7 +128,7 @@
         long size;
         long len;
         struct Queue* wait; // tasks waiting this dataGear
-    } meta;
+    } Meta;
     struct Context Context;
     struct Time {
         union Data* time;
@@ -301,6 +301,16 @@
             Black,
         } color;
     } Node;
+    struct Atomic {
+        union Data* atomic;
+        union Data* data;
+        enum Code checkAndSet;
+        enum Code next;
+        enum Code fail;
+    } Atomic;
+    struct AtomicReference {
+        union Data* data;
+    } AtomicReference;
     struct Semaphore {
         union Data* semaphore;
         enum Code p;
--- a/src/parallel_execution/examples/twice/twice.cbc	Mon Nov 06 19:04:41 2017 +0900
+++ b/src/parallel_execution/examples/twice/twice.cbc	Tue Nov 21 04:28:36 2017 +0900
@@ -34,11 +34,10 @@
         buffer->outputData = NULL;
         buffer->inputLen = 2;
         buffer->outputLen = 0;
-        //continuationにそってGPUworkerに戻る
-        outputArray->array = inputArray->array;
         Executor* executor = context->worker->worker->CUDAWorker.executor;
         executor->executor->CUDAExecutor.buffer = buffer;
         cudaLoadFunction(context, "c/examples/twice/CUDAtwice.ptx", "twice");
+        outputArray->array = inputArray->array;
         Gearef(context, Executor)->executor = (union Data*)executor;
         Gearef(context, Executor)->task = context;
         Gearef(context, Executor)->next = context->next;