summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-06-11 21:40:31 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-06-11 21:40:31 -0500
commit24e81bc664f5cdbfc8be1badf00b025ec122af00 (patch)
tree2d41e3305fb903024541d105dfec6adf1824839a /src/kernel
parent165e6bed506f9fddd7e9da8ad1f4c7f186e29b00 (diff)
downloadtalos-hostboot-24e81bc664f5cdbfc8be1badf00b025ec122af00.tar.gz
talos-hostboot-24e81bc664f5cdbfc8be1badf00b025ec122af00.zip
Add mutex userspace / syscalls.
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/syscall.C66
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);
+ }
};
OpenPOWER on IntegriCloud