From 24e81bc664f5cdbfc8be1badf00b025ec122af00 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Fri, 11 Jun 2010 21:40:31 -0500 Subject: Add mutex userspace / syscalls. --- src/kernel/syscall.C | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'src/kernel') 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 #include #include +#include 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); + } }; -- cgit v1.2.1