summaryrefslogtreecommitdiffstats
path: root/src/include/sys
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-10-03 16:12:51 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-10-24 13:33:20 -0500
commit4962a22309cd7e3586aa57817689b18d67ca71c7 (patch)
tree2bfd610d6ed048f7d4a35717211eca06b15d1f69 /src/include/sys
parent21185b30cd99a00f01e15edba28402cdc00de1d1 (diff)
downloadtalos-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.h23
-rw-r--r--src/include/sys/task.h82
-rw-r--r--src/include/sys/vfs.h7
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
OpenPOWER on IntegriCloud