[Cbe-oss-dev] [PATCH 06/11]MARS: Add task exit code support
Yuji Mano
yuji.mano at am.sony.com
Fri Sep 12 05:34:51 EST 2008
This adds support for the MARS task API to be able to return the exit_code
returned by mars_task_main or passed into mars_task_exit, to the user. The
exit_code can be obtained when calling mars_task_wait. It is left up to the
user how they will handle any errors returned by the task program.
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
include/common/mars/mars_task_types.h | 3 +-
include/host/mars/mars_task.h | 6 +++-
include/mpu/mars/mars_task.h | 10 +++++--
src/host/lib/mars_task.c | 12 +++++++--
src/mpu/kernel/mars_kernel_scheduler.c | 11 +++-----
src/mpu/lib/mars_entry.S | 2 -
src/mpu/lib/mars_task.c | 42 ++++++++++++++++++++++++++++-----
7 files changed, 64 insertions(+), 22 deletions(-)
--- a/include/common/mars/mars_task_types.h
+++ b/include/common/mars/mars_task_types.h
@@ -162,7 +162,8 @@ struct mars_task_context {
uint32_t stack; /* stack pointer of exec */
uint32_t context_save_size; /* context save size */
uint64_t context_save_area; /* context save area */
- uint8_t pad[24]; /* padding */
+ int32_t exit_code; /* exit code */
+ uint8_t pad[20]; /* padding */
} __attribute__((aligned(MARS_TASK_CONTEXT_ALIGN)));
#if defined(__cplusplus)
--- a/include/host/mars/mars_task.h
+++ b/include/host/mars/mars_task.h
@@ -179,13 +179,14 @@ int mars_task_schedule(struct mars_task_
* This function will block until the scheduled task specified is finished.
*
* \param[in] id - pointer to task id to wait for
+ * \param[in] exit_code - pointer to variable to store task exit code
* \return
* MARS_SUCCESS - task execution finished
* \n MARS_ERROR_NULL - null pointer specified
* \n MARS_ERROR_PARAMS - bad task id specified
* \n MARS_ERROR_STATE - task is in an invalid state
*/
-int mars_task_wait(struct mars_task_id *id);
+int mars_task_wait(struct mars_task_id *id, int32_t *exit_code);
/**
* \ingroup group_mars_task
@@ -195,6 +196,7 @@ int mars_task_wait(struct mars_task_id *
* or not and return immediately without blocking.
*
* \param[in] id - pointer to task id to wait for
+ * \param[in] exit_code - pointer to variable to store task exit code
* \return
* MARS_SUCCESS - task execution finished
* \n MARS_ERROR_NULL - null pointer specified
@@ -202,7 +204,7 @@ int mars_task_wait(struct mars_task_id *
* \n MARS_ERROR_STATE - task is in an invalid state
* \n MARS_ERROR_BUSY - task has not yet finished execution
*/
-int mars_task_try_wait(struct mars_task_id *id);
+int mars_task_try_wait(struct mars_task_id *id, int32_t *exit_code);
#if defined(__cplusplus)
}
--- a/include/mpu/mars/mars_task.h
+++ b/include/mpu/mars/mars_task.h
@@ -78,8 +78,10 @@ int mars_task_main(const struct mars_tas
* function will cause the task to enter the finished state, and will no
* longer be scheduled to run. This function does not need to be called when
* returning from \ref mars_task_main since it is called automatically.
+ *
+ * \param[in] exit_code - value to be returned to the task wait call
*/
-void mars_task_exit(void);
+void mars_task_exit(int32_t exit_code);
/**
* \ingroup group_mars_task
@@ -138,6 +140,7 @@ int mars_task_schedule(struct mars_task_
* This function will block until the scheduled task specified is finished.
*
* \param[in] id - pointer to task id to wait for
+ * \param[in] exit_code - pointer to variable to store task exit code
* \return
* MARS_SUCCESS - task execution finished
* \n MARS_ERROR_NULL - null pointer specified
@@ -145,7 +148,7 @@ int mars_task_schedule(struct mars_task_
* \n MARS_ERROR_STATE - task is in an invalid state
* \n MARS_ERROR_FORMAT - no context save area specified
*/
-int mars_task_wait(struct mars_task_id *id);
+int mars_task_wait(struct mars_task_id *id, int32_t *exit_code);
/**
* \ingroup group_mars_task
@@ -155,6 +158,7 @@ int mars_task_wait(struct mars_task_id *
* or not and return immediately without blocking.
*
* \param[in] id - pointer to task id to wait for
+ * \param[in] exit_code - pointer to variable to store task exit code
* \return
* MARS_SUCCESS - task execution finished
* \n MARS_ERROR_NULL - null pointer specified
@@ -162,7 +166,7 @@ int mars_task_wait(struct mars_task_id *
* \n MARS_ERROR_STATE - task is in an invalid state
* \n MARS_ERROR_BUSY - task has not yet finished execution
*/
-int mars_task_try_wait(struct mars_task_id *id);
+int mars_task_try_wait(struct mars_task_id *id, int32_t *exit_code);
/**
* \ingroup group_mars_task
--- a/src/host/lib/mars_task.c
+++ b/src/host/lib/mars_task.c
@@ -185,7 +185,7 @@ int mars_task_schedule(struct mars_task_
return MARS_SUCCESS;
}
-int mars_task_wait(struct mars_task_id *id)
+int mars_task_wait(struct mars_task_id *id, int32_t *exit_code)
{
MARS_CHECK_RET(id, MARS_ERROR_NULL);
MARS_CHECK_RET(id->mars_context_ea, MARS_ERROR_PARAMS);
@@ -200,10 +200,14 @@ int mars_task_wait(struct mars_task_id *
(struct mars_workload_context **)&task);
MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
+ /* exit_code requested so return it to caller */
+ if (exit_code)
+ *exit_code = task->exit_code;
+
return MARS_SUCCESS;
}
-int mars_task_try_wait(struct mars_task_id *id)
+int mars_task_try_wait(struct mars_task_id *id, int32_t *exit_code)
{
MARS_CHECK_RET(id, MARS_ERROR_NULL);
MARS_CHECK_RET(id->mars_context_ea, MARS_ERROR_PARAMS);
@@ -218,5 +222,9 @@ int mars_task_try_wait(struct mars_task_
(struct mars_workload_context **)&task);
MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
+ /* exit_code requested so return it to caller */
+ if (exit_code)
+ *exit_code = task->exit_code;
+
return MARS_SUCCESS;
}
--- a/src/mpu/kernel/mars_kernel_scheduler.c
+++ b/src/mpu/kernel/mars_kernel_scheduler.c
@@ -223,13 +223,10 @@ void release_workload(void)
int block = workload_index / MARS_WORKLOAD_PER_BLOCK;
int index = workload_index % MARS_WORKLOAD_PER_BLOCK;
- /* dma updated workload context back to main memory if not finished */
- if (workload_state != MARS_WORKLOAD_STATE_FINISHED) {
- mars_dma_put_and_wait((void *)&workload,
- workload_ea,
- sizeof(struct mars_workload_context),
- MARS_DMA_TAG);
- }
+ mars_dma_put_and_wait((void *)&workload,
+ workload_ea,
+ sizeof(struct mars_workload_context),
+ MARS_DMA_TAG);
/* release block reservation */
release_block(block, index);
--- a/src/mpu/lib/mars_entry.S
+++ b/src/mpu/lib/mars_entry.S
@@ -80,4 +80,4 @@ mars_entry:
brsl $lr, mars_task_main
/* call kernel syscall exit */
- br mars_exit
+ br mars_task_exit
--- a/src/mpu/lib/mars_task.c
+++ b/src/mpu/lib/mars_task.c
@@ -41,8 +41,15 @@
#include "mars/mars_error.h"
#include "mars/mars_debug.h"
-void mars_task_exit(void)
+void mars_task_exit(int32_t exit_code)
{
+ struct mars_task_context *task;
+
+ task = (struct mars_task_context *)mars_get_workload();
+
+ /* save the exit code in the task context */
+ task->exit_code = exit_code;
+
mars_exit();
}
@@ -61,8 +68,7 @@ int mars_task_yield(void)
return MARS_SUCCESS;
}
-int mars_task_schedule(struct mars_task_id *id,
- struct mars_task_args *args,
+int mars_task_schedule(struct mars_task_id *id, struct mars_task_args *args,
uint8_t priority)
{
MARS_CHECK_RET(id, MARS_ERROR_NULL);
@@ -70,7 +76,7 @@ int mars_task_schedule(struct mars_task_
return mars_schedule(id->workload_id, args, priority);
}
-int mars_task_wait(struct mars_task_id *id)
+int mars_task_wait(struct mars_task_id *id, int32_t *exit_code)
{
MARS_CHECK_RET(id, MARS_ERROR_NULL);
@@ -88,14 +94,38 @@ int mars_task_wait(struct mars_task_id *
mars_signal_wait();
+ /* exit code requested so get it from the task context and return it */
+ if (exit_code) {
+ task = (struct mars_task_context *)
+ mars_get_workload_by_id(id->workload_id);
+ MARS_CHECK_RET(task, MARS_ERROR_INTERNAL);
+
+ *exit_code = task->exit_code;
+ }
+
return MARS_SUCCESS;
}
-int mars_task_try_wait(struct mars_task_id *id)
+int mars_task_try_wait(struct mars_task_id *id, int32_t *exit_code)
{
MARS_CHECK_RET(id, MARS_ERROR_NULL);
- return mars_try_wait(id->workload_id);
+ int ret;
+ struct mars_task_context *task;
+
+ ret = mars_try_wait(id->workload_id);
+ MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
+
+ /* exit code requested so get it from the task context and return it */
+ if (exit_code) {
+ task = (struct mars_task_context *)
+ mars_get_workload_by_id(id->workload_id);
+ MARS_CHECK_RET(task, MARS_ERROR_INTERNAL);
+
+ *exit_code = task->exit_code;
+ }
+
+ return MARS_SUCCESS;
}
uint32_t mars_task_get_kernel_id(void)
More information about the cbe-oss-dev
mailing list