diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-10-03 16:12:51 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-10-24 13:33:20 -0500 |
commit | 4962a22309cd7e3586aa57817689b18d67ca71c7 (patch) | |
tree | 2bfd610d6ed048f7d4a35717211eca06b15d1f69 /src/kernel/syscall.C | |
parent | 21185b30cd99a00f01e15edba28402cdc00de1d1 (diff) | |
download | talos-hostboot-4962a22309cd7e3586aa57817689b18d67ca71c7.tar.gz talos-hostboot-4962a22309cd7e3586aa57817689b18d67ca71c7.zip |
Support task_wait / task_wait_tid syscalls:
- Add task_end2 syscall to allow pthread_exit-like retval.
- Add/maintain task states.
- Create task parent/child tracking tree.
- Add task_detach function.
- Implement wait syscalls.
Make task_exec caller the parent of spawned task:
Previously the task_exec call caused a message to the
VFS task, which called task_create and returned the tid
in response to the message. This causes the parent of
the spawned task to appear to be the VFS task.
Modify task_exec / VFS handling to instead return the
entry point address on the message and have task_exec call
task_create directly itself.
Change-Id: I6b6796f45875de37b1ab01e7596639b073820b95
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/443
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r-- | src/kernel/syscall.C | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index cb4650c7a..53fdb287e 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -62,6 +62,7 @@ namespace Systemcalls void TaskStart(task_t*); void TaskEnd(task_t*); void TaskMigrateToMaster(task_t*); + void TaskWait(task_t*); void MsgQCreate(task_t*); void MsgQDestroy(task_t*); void MsgQRegisterRoot(task_t*); @@ -91,6 +92,7 @@ namespace Systemcalls &TaskStart, // TASK_START &TaskEnd, // TASK_END &TaskMigrateToMaster, // TASK_MIGRATE_TO_MASTER + &TaskWait, // TASK_WAIT &MsgQCreate, // MSGQ_CREATE &MsgQDestroy, // MSGQ_DESTROY @@ -163,19 +165,8 @@ namespace Systemcalls void TaskEnd(task_t* t) { - // Make sure task pointers are updated before we delete this task. - t->cpu->scheduler->setNextRunnable(); - - // TODO: Deal with join. - - // Clean up task memory. - // Delete FP context. - if (t->fp_context) - delete t->fp_context; - // Delete stack. - StackSegment::deleteStack(t->tid); - // Delete task struct. - delete t; + TaskManager::endTask(t, (void*)TASK_GETARG0(t), + TASK_STATUS_EXITED_CLEAN); } void TaskMigrateToMaster(task_t* t) @@ -194,6 +185,46 @@ namespace Systemcalls t->cpu->scheduler->setNextRunnable(); } + void TaskWait(task_t* t) + { + int64_t tid = static_cast<int64_t>(TASK_GETARG0(t)); + int* status = reinterpret_cast<int*>(TASK_GETARG1(t)); + void** retval = reinterpret_cast<void**>(TASK_GETARG2(t)); + + // Validate status address and convert to kernel address. + if (status != NULL) + { + uint64_t addr = + VmmManager::findPhysicalAddress( + reinterpret_cast<uint64_t>(status)); + + if (addr == (static_cast<uint64_t>(-EFAULT))) + { + TASK_SETRTN(t, -EFAULT); + return; + } + status = reinterpret_cast<int*>(addr); + } + + // Validate retval address and convert to kernel address. + if (retval != NULL) + { + uint64_t addr = + VmmManager::findPhysicalAddress( + reinterpret_cast<uint64_t>(retval)); + + if (addr == (static_cast<uint64_t>(-EFAULT))) + { + TASK_SETRTN(t, -EFAULT); + return; + } + retval = reinterpret_cast<void**>(addr); + } + + // Perform wait. + TaskManager::waitTask(t, tid, status, retval); + } + void MsgQCreate(task_t* t) { TASK_SETRTN(t, (uint64_t) new MessageQueue()); @@ -281,6 +312,8 @@ namespace Systemcalls MessagePending* mp = new MessagePending(); mp->key = m; mp->task = t; + t->state = TASK_STATE_BLOCK_MSG; + t->state_info = mq; mq->lock.lock(); @@ -355,6 +388,8 @@ namespace Systemcalls if (NULL == mp) { mq->waiting.insert(t); + t->state = TASK_STATE_BLOCK_MSG; + t->state_info = mq; t->cpu->scheduler->setNextRunnable(); } else @@ -414,8 +449,7 @@ namespace Systemcalls TimeManager::delayTask(t, TASK_GETARG0(t), TASK_GETARG1(t)); TASK_SETRTN(t, 0); - Scheduler* s = t->cpu->scheduler; - s->setNextRunnable(); + t->cpu->scheduler->setNextRunnable(); } /** @@ -445,7 +479,7 @@ namespace Systemcalls { printk("Task %d terminated. No physical address found for address 0x%p", t->tid, (void *) uaddr); - TaskEnd(t); + TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED); } } @@ -470,7 +504,7 @@ namespace Systemcalls { printk("Task %d terminated. No physical address found for address 0x%p", t->tid, (void *) uaddr); - TaskEnd(t); + TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED); } } @@ -529,12 +563,12 @@ namespace Systemcalls * @param[in] t: The task used to set Page Permissions for a given block */ void MmSetPermission(task_t* t) - { + { void* va = (void*)TASK_GETARG0(t); uint64_t size = (uint64_t)TASK_GETARG1(t); PAGE_PERMISSIONS access_type = (PAGE_PERMISSIONS)TASK_GETARG2(t); - + TASK_SETRTN(t, VmmManager::mmSetPermission(va,size, access_type)); } - + }; |