changeset 506:04441dd783c5

Add LockImpl
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Tue, 02 Jan 2018 06:16:40 +0900
parents 528c31b045de
children a7127917c736
files src/parallel_execution/Lock.h src/parallel_execution/LockImpl.cbc src/parallel_execution/context.h
diffstat 3 files changed, 94 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/Lock.h	Tue Jan 02 06:16:40 2018 +0900
@@ -0,0 +1,6 @@
+typedef struct Lock<Impl>{
+        union Data* lock;
+        __code doLock(Impl* lock, __code next(...)); 
+        __code doUnlock(Impl* lock, __code next(...)); 
+        __code next(...);
+} Lock;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/LockImpl.cbc	Tue Jan 02 06:16:40 2018 +0900
@@ -0,0 +1,77 @@
+#include "../context.h"
+#interface "Queue.h"
+#interface "Atomic.h"
+#interface "Lock.h"
+
+Lock* createLockImpl(struct Context* context) {
+    struct Lock* lock = new Lock();
+    struct LockImpl* lockImpl = new LockImpl();
+    lockImpl->lock = NULL;
+    lockImpl->waitThreadList = createSynchornizedQueue(context);
+    lockImpl->atomic = createAtomicReference(context);
+    lock->lock = (union Data*)lockImpl;
+    lock->DoLock = C_doLockLockImpl;
+    lock->DoUnlock = C_doUnlockLockImpl;
+    return lock;
+}
+
+__code doLockLockImpl(struct LockImpl* lock, __code next(...)) {
+    struct Atomic atomic = lock->atomic;
+    goto atomic->checkAndSet(&lockImpl->lock, NULL, 1, doLockLockImpl1, doLockLockImpl2);
+}
+
+__code doLockLockImpl1(struct LockImpl* lock, __code next(...)) {
+    lock->lockContext = context;
+    goto next(...);
+}
+
+__code doLockLockImpl2(struct LockImpl* lock, __code next(...)) {
+    struct Queue queue = lock->waitThreadList;
+    context->next= C_doLockLockImpl;
+    goto queue->put(context, doLockLockImpl3);
+}
+
+__code doLockLockImpl3(struct LockImpl* lock, struct Worker* worker, __code next(...)) {
+    goto worker->taskReceive(); // goto shceduler
+}
+
+__code doLockLockImpl3(struct Context* context) {
+    // switch worker context
+    struct Context* workerContext = context->worker->worker->CPUWorker.context;
+    LockImpl* lockImpl = (LockImpl*)GearImpl(context, Lock, lockImpl);
+    goto doLockLockImpl3(workerContext,
+                         lockImpl,
+                         context->worker,
+                         Gearef(context, Semaphore)->next);
+}
+
+__code doUnlockLockImpl(struct LockImpl* lock, __code next(...)) {
+    if (lock->lockContext == context) {
+        goto atomic->checkAndSet(&lockImpl->lock, 1, NULL, doUnlockLockImpl1, next(...));
+    }
+    goto next(...);
+}
+
+__code doUnlockLockImpl1(struct LockImpl* lock, __code next(...)) {
+    struct Queue* queue = lock->waitThreadQueue;
+    goto queue->isEmpty(doUnlockLockImpl2, next(...));
+}
+
+__code doUnlockLockImpl2(struct LockImpl* lock, __code next(...)) {
+    struct Queue* queue = lock->waitThreadQueue;
+    goto queue->take(doUnlockLockImpl3);
+}
+
+__code doUnlockLockImpl3(struct LockImpl* lock, struct Context* waitTask, __code next(...)) {
+    struct TaskManager* taskManager = waitTask->taskManager;
+    goto taskManager->spawn(waitTask, next(...)); //notify
+}
+
+__code doUnlockLockImpl3_stub(struct Context* context) {
+    LockImpl* lockImpl = (LockImpl*)GearImpl(context, Lock, lock);
+    struct Context* waitTask = &Gearef(context, Queue)->data->Context;
+    goto doUnlockLockImpl3(context,
+                           lockImpl,
+                           waitTask,
+                           Gearef(context, Lock)->next);
+}
--- a/src/parallel_execution/context.h	Tue Jan 02 02:23:41 2018 +0900
+++ b/src/parallel_execution/context.h	Tue Jan 02 06:16:40 2018 +0900
@@ -414,6 +414,17 @@
         struct Semaphore* emptyCount;
         struct Semaphore* lock;
     } BoundedBuffer;
+    struct Lock {
+        union Data* lock;
+        enum Code doLock;
+        enum Code doUnLock;
+        enum Code next;
+    } lock;
+    struct LockImpl {
+        Int* lock;
+        struct Queue waitThreadList;
+        struct Atomic atomic;
+    } lockImpl;
 }; // union Data end       this is necessary for context generator
 typedef union Data Data;