Patchwork MARS: Add task exit code support

login
register
mail settings
Submitter Yuji Mano
Date Sept. 11, 2008, 7:34 p.m.
Message ID <48C972DB.1090900@am.sony.com>
Download mbox | patch
Permalink /patch/239/
State New
Delegated to: Yuji Mano
Headers show

Comments

Yuji Mano - Sept. 11, 2008, 7:34 p.m.
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@am.sony.com>
Kazunori Asayama - Sept. 12, 2008, 8:15 a.m.
Yuji Mano wrote:
> 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@am.sony.com>

Acked-by: Kazunori Asayama <asayama@sm.sony.co.jp>

> 
> ---
>  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(-)
>

Patch

--- 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)