diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-06-11 21:40:31 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-06-11 21:40:31 -0500 |
commit | 24e81bc664f5cdbfc8be1badf00b025ec122af00 (patch) | |
tree | 2d41e3305fb903024541d105dfec6adf1824839a /src/kernel | |
parent | 165e6bed506f9fddd7e9da8ad1f4c7f186e29b00 (diff) | |
download | talos-hostboot-24e81bc664f5cdbfc8be1badf00b025ec122af00.tar.gz talos-hostboot-24e81bc664f5cdbfc8be1badf00b025ec122af00.zip |
Add mutex userspace / syscalls.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/syscall.C | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index b993bf222..ce26970c7 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -6,6 +6,7 @@ #include <kernel/syscalls.H> #include <kernel/console.H> #include <kernel/pagemgr.H> +#include <kernel/usermutex.H> extern "C" void kernel_execute_decrementer() @@ -26,6 +27,10 @@ namespace Systemcalls void TaskStart(task_t*); void TaskEnd(task_t*); void TaskGettid(task_t*); + void MutexCreate(task_t*); + void MutexDestroy(task_t*); + void MutexLockCont(task_t*); + void MutexUnlockCont(task_t*); syscall syscalls[] = { @@ -33,6 +38,11 @@ namespace Systemcalls &TaskStart, &TaskEnd, &TaskGettid, + + &MutexCreate, + &MutexDestroy, + &MutexLockCont, + &MutexUnlockCont, }; }; @@ -103,4 +113,60 @@ namespace Systemcalls { TASK_SETRTN(t, t->tid); } + + void MutexCreate(task_t* t) + { + UserMutex * m = new UserMutex(); + TASK_SETRTN(t, (uint64_t)m); + } + + void MutexDestroy(task_t* t) + { + // TODO: Extra verification of parameter and mutex state. + + delete (UserMutex*) TASK_GETARG0(t); + TASK_SETRTN(t, 0); + } + + void MutexLockCont(task_t* t) + { + // TODO: Extra verification of parameter and mutex state. + + UserMutex* m = (UserMutex*) TASK_GETARG0(t); + m->lock.lock(); + if (m->unlock_pend) + { + // We missed the unlock syscall, take lock and return to userspace. + m->unlock_pend = false; + m->lock.unlock(); + + } + else + { + // Queue ourself to wait for unlock. + m->waiting.insert(TaskManager::getCurrentTask()); + m->lock.unlock(); + CpuManager::getCurrentCPU()->scheduler->setNextRunnable(); + } + TASK_SETRTN(t, 0); + } + + void MutexUnlockCont(task_t* t) + { + // TODO: Extra verification of parameter and mutex state. + + UserMutex* m = (UserMutex*) TASK_GETARG0(t); + m->lock.lock(); + task_t* wait_task = m->waiting.remove(); + if (NULL == wait_task) + { + m->unlock_pend = true; + } + else + { + wait_task->cpu->scheduler->addTask(wait_task); + } + m->lock.unlock(); + TASK_SETRTN(t, 0); + } }; |