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/include/sys | |
| 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/include/sys')
| -rw-r--r-- | src/include/sys/syscall.h | 23 | ||||
| -rw-r--r-- | src/include/sys/task.h | 82 | ||||
| -rw-r--r-- | src/include/sys/vfs.h | 7 |
3 files changed, 106 insertions, 6 deletions
diff --git a/src/include/sys/syscall.h b/src/include/sys/syscall.h index f0972e949..b3d435edf 100644 --- a/src/include/sys/syscall.h +++ b/src/include/sys/syscall.h @@ -23,13 +23,21 @@ #ifndef __SYS_SYSCALL_H #define __SYS_SYSCALL_H +/** @file syscall.h + * @brief Defines syscall wrapper functions to get C-caller to put syscall + * parameters in the correct spots for ABI so kernel can pull them + * from the right position in the task structs. + */ + #ifdef __cplusplus -extern "C" +extern "C" { #endif #include <stdint.h> +#include <builtins.h> +// Normal system calls. void* _syscall0(uint64_t); void* _syscall1(uint64_t, void*); void* _syscall2(uint64_t, void*, void*); @@ -39,6 +47,19 @@ void* _syscall5(uint64_t, void*, void*, void*, void*, void*); void* _syscall6(uint64_t, void*, void*, void*, void*, void*, void*); void* _syscall7(uint64_t, void*, void*, void*, void*, void*, void*, void*); +// System calls which never return. Marked NO_RETURN so the compiler +// can make additional optimizations. +void* _syscall0_nr(uint64_t) NO_RETURN; +void* _syscall1_nr(uint64_t, void*) NO_RETURN; +void* _syscall2_nr(uint64_t, void*, void*) NO_RETURN; +void* _syscall3_nr(uint64_t, void*, void*, void*) NO_RETURN; +void* _syscall4_nr(uint64_t, void*, void*, void*, void*) NO_RETURN; +void* _syscall5_nr(uint64_t, void*, void*, void*, void*, void*) NO_RETURN; +void* _syscall6_nr(uint64_t, void*, void*, void*, void*, void*, void*) + NO_RETURN; +void* _syscall7_nr(uint64_t, void*, void*, void*, void*, void*, void*, void*) + NO_RETURN; + #ifdef __cplusplus } #include <kernel/syscalls.H> diff --git a/src/include/sys/task.h b/src/include/sys/task.h index 9f43996c4..0627784f1 100644 --- a/src/include/sys/task.h +++ b/src/include/sys/task.h @@ -27,6 +27,7 @@ #define __SYS_TASK_H #include <stdint.h> +#include <builtins.h> #include <kernel/types.h> #ifdef __cplusplus @@ -64,7 +65,17 @@ tid_t task_create(void(*start_routine)(void*), void* arg); * function. Therefore, returning from the entry point function will * also cause the task to end cleanly using this function. */ -void task_end(); +void task_end() NO_RETURN; + +/** @fn task_end2 + * @brief End the calling task with a return value. + * + * See POSIX pthread_exit. + * + * @param[in] retval - A pointer to return to the task performing task_join / + * task_wait on this task. + */ +void task_end2(void* retval) NO_RETURN; /** @fn task_gettid * @brief Get task ID of calling task. @@ -130,6 +141,75 @@ void task_affinity_unpin(); */ void task_affinity_migrate_to_master(); +/** @enum task_status + * @brief Status of how a task exited. + */ +enum task_status +{ + /** Task called task_end cleanly. */ + TASK_STATUS_EXITED_CLEAN, + /** Task crashed. Ended by the kernel due to error. */ + TASK_STATUS_CRASHED, +}; + +/** @fn task_detach + * @brief Sets the calling task to the 'detached' state, meaning no parent + * may task_wait_tid on it. + */ +void task_detach(); + +/** @fn task_wait_tid + * @brief Block calling task until a requested child process exits. + * + * See also: POSIX 'waitid' / Linux 'waitpid'. + * + * @param[in] tid - Task to wait for completion. + * + * @param[out] status - Optional address to write child status. + * @param[out] retval - Optional address to write return-value. + * + * Status values come from task_status enumeration. + * Retval values come from child's 'task_end2' parameter. + * + * @note All non-detached tasks must be waited on by their parent to ensure + * there are not kernel memory-leaks. + * + * @note If a parent task ends prior to waiting on its children, the children + * become parented by their grand-parents, who must do the wait. + * + * @return tid of child waited on or negative number on error. + * + * @retval EDEADLK - Performing this wait would deadlock the caller such as + * when it has no children. + * @retval EFAULT - Bad memory address given for status or retval parameter. + */ +tid_t task_wait_tid(tid_t tid, int* status, void** retval); + +/** @fn task_wait + * @brief Block calling task until any child process exits. + * + * See also: Linux 'wait'. + * + * @param[out] status - Optional address to write child status. + * @param[out] retval - Optional address to write return-value. + * + * Status values come from task_status enumeration. + * Retval values come from child's 'task_end2' parameter. + * + * @note All non-detached tasks must be waited on by their parent to ensure + * there are not kernel memory-leaks. + * + * @note If a parent task ends prior to waiting on its children, the children + * become parented by their grand-parents, who must do the wait. + * + * @return tid of child waited on or negative number on error. + * + * @retval EDEADLK - Performing this wait would deadlock the caller such as + * when it has no children. + * @retval EFAULT - Bad memory address given for status or retval parameter. + */ +tid_t task_wait(int* status, void** retval); + #ifdef __cplusplus } #endif diff --git a/src/include/sys/vfs.h b/src/include/sys/vfs.h index 6ab24c9b8..d427c0abb 100644 --- a/src/include/sys/vfs.h +++ b/src/include/sys/vfs.h @@ -102,14 +102,13 @@ extern uint64_t VFS_LAST_ADDRESS; VfsSystemModule * vfs_find_module(VfsSystemModule * i_table, const char * i_name); /** - * Call the module start routine + * Get the module's start routine * @param[in] i_module VfsSystemModule data for the module - * @param[in] i_param parameter to pass to task_create() for this module - * @return tid_t of started task or negative value on error. + * @return Function pointer of module's start or negative value on error. * @retval -ENOENT if i_module is NULL * @retval -ENOEXEC if there is no start() */ -tid_t vfs_exec(VfsSystemModule * i_module, void* i_param); +void* vfs_start_entrypoint(VfsSystemModule * i_module); /** * Change permissions on the virtual pages associated with the module |

