Mercurial > hg > Members > Moririn
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;