From patchwork Thu Sep 11 19:34:51 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuji Mano X-Patchwork-Id: 239 X-Patchwork-Delegate: yuji.mano@am.sony.com Return-Path: X-Original-To: patchwork@ozlabs.org Delivered-To: patchwork@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 59C42DE607 for ; Fri, 12 Sep 2008 06:37:56 +1000 (EST) X-Original-To: cbe-oss-dev@ozlabs.org Delivered-To: cbe-oss-dev@ozlabs.org Received: from WA4EHSOBE004.bigfish.com (outbound-wa4.frontbridge.com [216.32.181.16]) by ozlabs.org (Postfix) with ESMTP id 1A914DE01F for ; Fri, 12 Sep 2008 06:37:15 +1000 (EST) Received: from mail120-wa4-R.bigfish.com (10.8.14.246) by WA4EHSOBE004.bigfish.com (10.8.40.24) with Microsoft SMTP Server id 8.1.291.1; Thu, 11 Sep 2008 20:37:12 +0000 Received: from mail120-wa4 (localhost.localdomain [127.0.0.1]) by mail120-wa4-R.bigfish.com (Postfix) with ESMTP id 30862B811F for ; Thu, 11 Sep 2008 20:37:12 +0000 (UTC) X-BigFish: VS4(zzzz10c0j10d3izz1497iz2dh6bh61h) X-Spam-TCS-SCL: 0:0 X-FB-SS: 5, Received: by mail120-wa4 (MessageSwitch) id 1221165429723181_20695; Thu, 11 Sep 2008 20:37:09 +0000 (UCT) Received: from mail8.fw-sd.sony.com (mail8.fw-sd.sony.com [160.33.66.75]) by mail120-wa4.bigfish.com (Postfix) with ESMTP id 9769FE4005A for ; Thu, 11 Sep 2008 20:37:09 +0000 (UTC) Received: from mail3.sjc.in.sel.sony.com (mail3.sjc.in.sel.sony.com [43.134.1.211]) by mail8.fw-sd.sony.com (8.14.2/8.14.2) with ESMTP id m8BKb9oc021159 for ; Thu, 11 Sep 2008 20:37:09 GMT Received: from USSDIXIM02.am.sony.com (ussdixim02.am.sony.com [43.130.140.34]) by mail3.sjc.in.sel.sony.com (8.12.11/8.12.11) with ESMTP id m8BKb7tB021726 for ; Thu, 11 Sep 2008 20:37:08 GMT Received: from ussdixms03.am.sony.com ([43.130.140.23]) by USSDIXIM02.am.sony.com with Microsoft SMTPSVC(5.0.2195.6713); Thu, 11 Sep 2008 13:37:08 -0700 Received: from [43.135.148.175] ([43.135.148.175]) by ussdixms03.am.sony.com with Microsoft SMTPSVC(5.0.2195.6713); Thu, 11 Sep 2008 13:37:07 -0700 Message-ID: <48C972DB.1090900@am.sony.com> Date: Thu, 11 Sep 2008 12:34:51 -0700 From: Yuji Mano User-Agent: Thunderbird 2.0.0.5 (X11/20070719) MIME-Version: 1.0 To: CBE Development X-Enigmail-Version: 0.95.7 X-OriginalArrivalTime: 11 Sep 2008 20:37:07.0882 (UTC) FILETIME=[28A730A0:01C9144E] X-SEL-encryption-scan: scanned Subject: [Cbe-oss-dev] [PATCH 06/11]MARS: Add task exit code support X-BeenThere: cbe-oss-dev@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Discussion about Open Source Software for the Cell Broadband Engine List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: cbe-oss-dev-bounces+patchwork=ozlabs.org@ozlabs.org Errors-To: cbe-oss-dev-bounces+patchwork=ozlabs.org@ozlabs.org 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 Acked-by: Kazunori Asayama --- 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)