aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuji Mano <yuji.mano@am.sony.com>2009-03-24 18:48:22 -0700
committerYuji Mano <yuji.mano@am.sony.com>2009-03-26 17:23:27 -0700
commit5470c2bc5dcda1f400d46951a2fbed78286e0f39 (patch)
treec2780b4935e40dd50e5a52bb9236c8422cffa46d
parenta058f82afeef492b5fb350aefde9c548f20178ef (diff)
downloadmars-src-5470c2bc5dcda1f400d46951a2fbed78286e0f39.tar.gz
base: Add unschedule api
This patch adds the workload unschedule API to the kernel syscalls and workload module API. The unschedule API will allow for unscheduling of scheduled workloads that might become necessary in certain situations such as handling errors that might cause workloads to get stuck in a state that prevents it from finishing. Signed-off-by: Yuji Mano <yuji.mano@am.sony.com> Acked-by: Kazunori Asayama <asayama@sm.sony.co.jp>
-rw-r--r--base/include/host/mars/workload_queue.h74
-rw-r--r--base/include/mpu/mars/module.h61
-rw-r--r--base/src/common/kernel_internal_types.h5
-rw-r--r--base/src/common/workload_internal_types.h27
-rw-r--r--base/src/host/lib/workload_queue.c56
-rw-r--r--base/src/mpu/kernel/kernel.c145
-rw-r--r--base/src/mpu/lib/module.S48
7 files changed, 349 insertions, 67 deletions
diff --git a/base/include/host/mars/workload_queue.h b/base/include/host/mars/workload_queue.h
index f54d0c4..87581c5 100644
--- a/base/include/host/mars/workload_queue.h
+++ b/base/include/host/mars/workload_queue.h
@@ -84,7 +84,7 @@ int mars_workload_queue_query(struct mars_context *mars,
*
* If workload_ea is not NULL, the ea of the workload will be returned.
*
- * This call will lock the workload queue until the matching call to
+ * The workload adding process is not completed until the matching call to
* \ref mars_workload_queue_add_end is made.
* The user should make any necessary updates to the returned workload context
* in between this begin call and the end call.
@@ -142,7 +142,7 @@ int mars_workload_queue_add_end(struct mars_context *mars,
*
* If workload_ea is not NULL, the ea of the workload will be returned.
*
- * This call will lock the workload queue until the matching call to
+ * The workload removing process is not completed until the matching call to
* \ref mars_workload_queue_remove_end is made.
* The user should make any necessary updates to the returned workload context
* in between this begin call and the end call.
@@ -194,7 +194,7 @@ int mars_workload_queue_remove_end(struct mars_context *mars,
*
* If workload_ea is not NULL, the ea of the workload will be returned.
*
- * This call will lock the workload queue until the matching call to
+ * The workload scheduling process is not completed until the matching call to
* \ref mars_workload_queue_schedule_end is made.
* The user should make any necessary updates to the returned workload context
* in between this begin call and the end call.
@@ -238,6 +238,74 @@ int mars_workload_queue_schedule_end(struct mars_context *mars,
/**
* \ingroup group_mars_workload_queue
+ * \brief <b>[host]</b> Begins unscheduling of specified workload.
+ *
+ * This function will begin unscheduling the workload specified.
+ * This only initiates the unscheduling of the workload.
+ * This function must be completed with a matching call to
+ * \ref mars_workload_queue_unschedule_end to guarantee the completion of the
+ * unscheduling.
+ *
+ * If workload_ea is not NULL, the ea of the workload will be returned.
+ *
+ * The workload unscheduling process is not completed until the matching call to
+ * \ref mars_workload_queue_unschedule_end is made.
+ * The user should make any necessary updates to the returned workload context
+ * in between this begin call and the end call.
+ *
+ * When a workload is unscheduled, it will be put into a finished state and any
+ * entities waiting on the workload to finish will be resumed.
+ *
+ * If a scheduled workload is unscheduled before execution, the workload will
+ * not be executed until a subsequent scheduling request is made.
+ *
+ * If the workload is currently in a waiting state, calling unschedule will
+ * finish the workload and will not be resumed from the waiting state.
+ *
+ * If the workload is currently in a running state, calling unschedule will
+ * immediately put the workload into a finished state. However, execution of the
+ * workload will only be suspended when the workload yields, waits, or finishes.
+ *
+ * \note
+ * Trying to unschedule a workload that has not yet been scheduled, or has
+ * already finished a previously scheduled execution will return an error.
+ *
+ * \param[in] mars - address of pointer to MARS context
+ * \param[in] id - id of workload
+ * \param[out] workload_ea - address of pointer to workload context ea
+ * \return
+ * MARS_SUCCESS - workload aborted
+ * \n MARS_ERROR_NULL - null pointer specified
+ * \n MARS_ERROR_PARAMS - invalid mars context or workload id specified
+ * \n MARS_ERROR_STATE - workload is not scheduled or has finished
+ */
+int mars_workload_queue_unschedule_begin(struct mars_context *mars,
+ uint16_t id,
+ uint64_t *workload_ea);
+
+/**
+ * \ingroup group_mars_workload_queue
+ * \brief <b>[host]</b> Ends unscheduling of specified workload.
+ *
+ * This function will complete an unschedule operation previously initiated with
+ * \ref mars_workload_queue_unschedule_begin.
+ * This function must be called in pair for each call to
+ * \ref mars_workload_queue_unschedule_begin to guarantee the completion of the
+ * initiated unschedule operation.
+ *
+ * \param[in] mars - address of pointer to MARS context
+ * \param[in] id - id of workload
+ * \return
+ * MARS_SUCCESS - workload unscheduling complete
+ * \n MARS_ERROR_NULL - null pointer specified
+ * \n MARS_ERROR_PARAMS - invalid mars context or workload id specified
+ * \n MARS_ERROR_STATE - workload unscheduling not started
+ */
+int mars_workload_queue_unschedule_end(struct mars_context *mars,
+ uint16_t id);
+
+/**
+ * \ingroup group_mars_workload_queue
* \brief <b>[host]</b> Waits for specified workload to finish.
*
* This function will block and wait until the specified workload finishes.
diff --git a/base/include/mpu/mars/module.h b/base/include/mpu/mars/module.h
index 33c4879..6103bff 100644
--- a/base/include/mpu/mars/module.h
+++ b/base/include/mpu/mars/module.h
@@ -193,7 +193,7 @@ int mars_module_workload_signal_reset(void);
* \ref mars_module_workload_schedule_end to guarantee the completion of the
* scheduling.
*
- * This call will lock the workload queue until the matching call to
+ * The workload scheduling process is not complete until the matching call to
* \ref mars_module_workload_schedule_end is made.
* The user should make any necessary updates to the returned workload context
* in between this begin call and the end call.
@@ -230,6 +230,65 @@ int mars_module_workload_schedule_end(uint16_t id, int cancel);
/**
* \ingroup group_mars_workload_module
+ * \brief <b>[MPU]</b> Begins unscheduling of specified workload.
+ *
+ * This function will begin unscheduling the workload specified.
+ * This only initiates the unscheduling of the workload.
+ * This function must be completed with a matching call to
+ * \ref mars_module_workload_unschedule_end to guarantee the completion of the
+ * unscheduling.
+ *
+ * The workload unscheduling process is not complete until the matching call to
+ * \ref mars_module_workload_unschedule_end is made.
+ * The user should make any necessary updates to the returned workload context
+ * in between this begin call and the end call.
+ *
+ * When a workload is unscheduled, it will be put into a finished state and any
+ * entities waiting on the workload to finish will be resumed.
+ *
+ * If a scheduled workload is unscheduled before execution, the workload will
+ * not be executed until a subsequent scheduling request is made.
+ *
+ * If the workload is currently in a waiting state, calling unschedule will
+ * finish the workload and will not be resumed from the waiting state.
+ *
+ * If the workload is currently in a running state, calling unschedule will
+ * immediately put the workload into a finished state. However, execution of the
+ * workload will only be suspended when the workload yields, waits, or finishes.
+ *
+ * \note
+ * Trying to unschedule a workload that has not yet been scheduled, or has
+ * already finished a previously scheduled execution will return an error.
+ *
+ * \param[in] id - id of workload
+ * \param[out] workload - address of pointer to workload context
+ * \return
+ * MARS_SUCCESS - workload unscheduling started
+ * \n MARS_ERROR_PARAMS - invalid workload id specified
+ * \n MARS_ERROR_STATE - workload is not scheduled or has finished
+ */
+int mars_module_workload_unschedule_begin(uint16_t id,
+ struct mars_workload_context **workload);
+
+/**
+ * \ingroup group_mars_workload_module
+ * \brief <b>[MPU]</b> Ends unscheduling of specified workload.
+ *
+ * This function will complete an unschedule operation previously initiated with
+ * \ref mars_module_workload_unschedule_begin.
+ * This function must be called in pair for each call to
+ * \ref mars_module_workload_unschedule_begin to guarantee the completion of the
+ * initiated unschedule operation.
+ *
+ * \return
+ * MARS_SUCCESS - workload unscheduling complete
+ * \n MARS_ERROR_PARAMS - invalid workload id specified
+ * \n MARS_ERROR_STATE - workload unscheduling not started
+ */
+int mars_module_workload_unschedule_end(uint16_t id);
+
+/**
+ * \ingroup group_mars_workload_module
* \brief <b>[MPU]</b> Returns execution to kernel with workload in wait state.
*
* This function will yield execution of the calling workload module and return
diff --git a/base/src/common/kernel_internal_types.h b/base/src/common/kernel_internal_types.h
index 8bd365b..3757764 100644
--- a/base/src/common/kernel_internal_types.h
+++ b/base/src/common/kernel_internal_types.h
@@ -76,8 +76,11 @@ struct mars_kernel_syscalls {
int (*workload_signal_set)(uint16_t id);
int (*workload_signal_reset)(void);
int (*workload_schedule_begin)(uint16_t id, uint8_t priority,
- struct mars_workload_context **workload);
+ struct mars_workload_context **workload);
int (*workload_schedule_end)(uint16_t id, int cancel);
+ int (*workload_unschedule_begin)(uint16_t id,
+ struct mars_workload_context **workload);
+ int (*workload_unschedule_end)(uint16_t id);
int (*host_signal_send)(uint64_t watch_point_ea);
int (*host_callback_set)(uint64_t callback_ea,
diff --git a/base/src/common/workload_internal_types.h b/base/src/common/workload_internal_types.h
index 5bfebc0..e4e018d 100644
--- a/base/src/common/workload_internal_types.h
+++ b/base/src/common/workload_internal_types.h
@@ -47,16 +47,17 @@
#define MARS_WORKLOAD_STATE_ADDING 0x01 /* adding now */
#define MARS_WORKLOAD_STATE_REMOVING 0x02 /* removing now */
#define MARS_WORKLOAD_STATE_SCHEDULING 0x04 /* scheduling now */
-#define MARS_WORKLOAD_STATE_READY 0x08 /* ready to schedule */
-#define MARS_WORKLOAD_STATE_WAITING 0x10 /* waiting for sync */
-#define MARS_WORKLOAD_STATE_RUNNING 0x20 /* currently running */
-#define MARS_WORKLOAD_STATE_FINISHED 0x40 /* not allow schedule */
+#define MARS_WORKLOAD_STATE_UNSCHEDULING 0x08 /* unscheduling now */
+#define MARS_WORKLOAD_STATE_READY 0x10 /* ready to schedule */
+#define MARS_WORKLOAD_STATE_WAITING 0x20 /* waiting for sync */
+#define MARS_WORKLOAD_STATE_RUNNING 0x40 /* currently running */
+#define MARS_WORKLOAD_STATE_FINISHED 0x80 /* not allow schedule */
#define MARS_WORKLOAD_PRIORITY_MIN 0x00 /* minimum priority */
#define MARS_WORKLOAD_PRIORITY_MAX 0xff /* maximum priority */
#define MARS_WORKLOAD_COUNTER_MIN 0x0000 /* minimum counter */
-#define MARS_WORKLOAD_COUNTER_MAX 0xffff /* maximum counter */
+#define MARS_WORKLOAD_COUNTER_MAX 0x7fff /* maximum counter */
#define MARS_WORKLOAD_SIGNAL_OFF 0x0 /* signal set off */
#define MARS_WORKLOAD_SIGNAL_ON 0x1 /* signal set on */
@@ -112,23 +113,23 @@
/*
* MARS workload queue block workload bits (64-bits)
* ------------------------------------------------------------------
- * |[63...57]|[56....49]|[48....33]|[ 32 ]|[31.....16]|[15......0]|
+ * |[63....56]|[55....48]|[47....33]|[ 32 ]|[31.....16]|[15......0]|
* ------------------------------------------------------------------
- * | 7-bits | 8-bits | 16-bits | 1-bit | 16-bits | 16-bits |
+ * | 8-bits | 8-bits | 15-bits | 1-bit | 16-bits | 16-bits |
* ------------------------------------------------------------------
- * | STATE | PRIORITY | COUNTER | SIGNAL | WAIT_ID | KERNEL_ID |
+ * | STATE | PRIORITY | COUNTER | SIGNAL | WAIT_ID | KERNEL_ID |
* ------------------------------------------------------------------
*/
-#define MARS_BITS_SHIFT_WORKLOAD_STATE 57
-#define MARS_BITS_SHIFT_WORKLOAD_PRIORITY 49
+#define MARS_BITS_SHIFT_WORKLOAD_STATE 56
+#define MARS_BITS_SHIFT_WORKLOAD_PRIORITY 48
#define MARS_BITS_SHIFT_WORKLOAD_COUNTER 33
#define MARS_BITS_SHIFT_WORKLOAD_SIGNAL 32
#define MARS_BITS_SHIFT_WORKLOAD_WAIT_ID 16
#define MARS_BITS_SHIFT_WORKLOAD_KERNEL_ID 0
-#define MARS_BITS_MASK_WORKLOAD_STATE 0xfe00000000000000ULL
-#define MARS_BITS_MASK_WORKLOAD_PRIORITY 0x01fe000000000000ULL
-#define MARS_BITS_MASK_WORKLOAD_COUNTER 0x0001fffe00000000ULL
+#define MARS_BITS_MASK_WORKLOAD_STATE 0xff00000000000000ULL
+#define MARS_BITS_MASK_WORKLOAD_PRIORITY 0x00ff000000000000ULL
+#define MARS_BITS_MASK_WORKLOAD_COUNTER 0x0000fffe00000000ULL
#define MARS_BITS_MASK_WORKLOAD_SIGNAL 0x0000000100000000ULL
#define MARS_BITS_MASK_WORKLOAD_WAIT_ID 0x00000000ffff0000ULL
#define MARS_BITS_MASK_WORKLOAD_KERNEL_ID 0x000000000000ffffULL
diff --git a/base/src/host/lib/workload_queue.c b/base/src/host/lib/workload_queue.c
index 90cdec7..adb12e7 100644
--- a/base/src/host/lib/workload_queue.c
+++ b/base/src/host/lib/workload_queue.c
@@ -761,6 +761,62 @@ int mars_workload_queue_schedule_end(struct mars_context *mars,
cancel ? NULL : update_header_bits);
}
+static int unscheduling_state_bits(uint64_t bits, uint64_t param)
+{
+ (void)param;
+
+ /* check for valid state */
+ switch (MARS_BITS_GET(&bits, WORKLOAD_STATE)) {
+ case MARS_WORKLOAD_STATE_READY:
+ case MARS_WORKLOAD_STATE_RUNNING:
+ case MARS_WORKLOAD_STATE_WAITING:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int mars_workload_queue_unschedule_begin(struct mars_context *mars,
+ uint16_t id,
+ uint64_t *workload_ea)
+{
+ return change_bits(mars, id, workload_ea,
+ unscheduling_state_bits, 0,
+ set_state_bits, MARS_WORKLOAD_STATE_UNSCHEDULING,
+ NULL);
+}
+
+int mars_workload_queue_unschedule_end(struct mars_context *mars,
+ uint16_t id)
+{
+ int ret;
+ int block;
+ int index;
+ uint64_t queue_ea;
+ uint64_t block_ea;
+ uint64_t bits_ea;
+
+ ret = change_state(mars, id, NULL,
+ MARS_WORKLOAD_STATE_UNSCHEDULING,
+ MARS_WORKLOAD_STATE_FINISHED,
+ update_header_bits);
+ if (ret != MARS_SUCCESS)
+ return ret;
+
+ queue_ea = mars->workload_queue_ea;
+
+ block = id / MARS_WORKLOAD_PER_BLOCK;
+ index = id % MARS_WORKLOAD_PER_BLOCK;
+
+ block_ea = get_block_ea(queue_ea, block);
+ bits_ea = get_block_bits_ea(block_ea, index);
+
+ /* signal any threads possibly waiting for workload to finish */
+ mars_ea_cond_signal(bits_ea, 1);
+
+ return MARS_SUCCESS;
+}
+
static int is_workload_finished(uint32_t upper, void *param)
{
(void)param;
diff --git a/base/src/mpu/kernel/kernel.c b/base/src/mpu/kernel/kernel.c
index 3806ead..0e5619a 100644
--- a/base/src/mpu/kernel/kernel.c
+++ b/base/src/mpu/kernel/kernel.c
@@ -58,15 +58,13 @@ static struct mars_workload_queue_header queue_header;
static struct mars_workload_queue_block queue_block;
/* workload */
+static struct mars_workload_context workload_buf;
static struct mars_workload_context workload;
static uint16_t workload_id;
static uint64_t workload_ea;
static uint8_t workload_state;
static uint8_t workload_is_cached;
-/* workload to schedule */
-static struct mars_workload_context schedule_workload;
-
/* workload module */
static struct mars_workload_module cached_workload_module;
static struct mars_workload_module *workload_module;
@@ -414,6 +412,28 @@ static int workload_signal_reset(void)
NULL);
}
+static void begin_callback(uint16_t id)
+{
+ /* get the workload context from workload queue */
+ dma_get(&workload_buf, get_workload_ea(id),
+ MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
+ dma_wait(MARS_KERNEL_DMA_TAG);
+
+ /* update queue header bits */
+ update_header_bits(id / MARS_WORKLOAD_PER_BLOCK);
+}
+
+static void end_callback(uint16_t id)
+{
+ /* put the workload context into workload queue */
+ dma_put((void *)&workload_buf, get_workload_ea(id),
+ MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
+ dma_wait(MARS_KERNEL_DMA_TAG);
+
+ /* update queue header bits */
+ update_header_bits(id / MARS_WORKLOAD_PER_BLOCK);
+}
+
static uint64_t set_schedule_bits(uint64_t bits, uint64_t priority)
{
/* set the info bits inside queue block for this workload */
@@ -426,14 +446,6 @@ static uint64_t set_schedule_bits(uint64_t bits, uint64_t priority)
return bits;
}
-static void schedule_begin_callback(uint16_t id)
-{
- /* get the workload context from workload queue */
- dma_get(&schedule_workload, get_workload_ea(id),
- MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
- dma_wait(MARS_KERNEL_DMA_TAG);
-}
-
static int workload_schedule_begin(uint16_t id, uint8_t priority,
struct mars_workload_context **workload)
{
@@ -443,35 +455,84 @@ static int workload_schedule_begin(uint16_t id, uint8_t priority,
ret = change_bits(id,
check_state_bits, MARS_WORKLOAD_STATE_FINISHED,
set_schedule_bits, priority,
- schedule_begin_callback);
+ begin_callback);
if (ret != MARS_SUCCESS)
return ret;
/* if requested set workload context pointer to return */
if (workload)
- *workload = &schedule_workload;
+ *workload = &workload_buf;
return MARS_SUCCESS;
}
-static void schedule_end_callback(uint16_t id)
-{
- /* put the workload context into workload queue */
- dma_put((void *)&schedule_workload, get_workload_ea(id),
- MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
- dma_wait(MARS_KERNEL_DMA_TAG);
-
- /* update queue header bits */
- update_header_bits(id / MARS_WORKLOAD_PER_BLOCK);
-}
-
static int workload_schedule_end(uint16_t id, int cancel)
{
return change_state(id,
MARS_WORKLOAD_STATE_SCHEDULING,
cancel ? MARS_WORKLOAD_STATE_FINISHED :
MARS_WORKLOAD_STATE_READY,
- cancel ? NULL : schedule_end_callback);
+ end_callback);
+}
+
+static int unscheduling_state_bits(uint64_t bits, uint64_t param)
+{
+ (void)param;
+
+ uint8_t state = MARS_BITS_GET(&bits, WORKLOAD_STATE);
+
+ return (state & (MARS_WORKLOAD_STATE_READY |
+ MARS_WORKLOAD_STATE_RUNNING |
+ MARS_WORKLOAD_STATE_WAITING));
+}
+
+static int workload_unschedule_begin(uint16_t id,
+ struct mars_workload_context **workload)
+{
+ int ret;
+
+ /* change bits necessary to begin unscheduling */
+ ret = change_bits(id,
+ unscheduling_state_bits, 0,
+ set_state_bits, MARS_WORKLOAD_STATE_UNSCHEDULING,
+ begin_callback);
+ if (ret != MARS_SUCCESS)
+ return ret;
+
+ /* if requested set workload context pointer to return */
+ if (workload)
+ *workload = &workload_buf;
+
+ return MARS_SUCCESS;
+}
+
+static void notify_host_bits(uint64_t block_ea, int index);
+
+static int workload_unschedule_end(uint16_t id)
+{
+ int ret;
+ int block;
+ int index;
+ uint64_t block_ea;
+
+ ret = change_state(id,
+ MARS_WORKLOAD_STATE_UNSCHEDULING,
+ MARS_WORKLOAD_STATE_FINISHED,
+ end_callback);
+ if (ret != MARS_SUCCESS)
+ return ret;
+
+ /* calculate block/index from id */
+ block = id / MARS_WORKLOAD_PER_BLOCK;
+ index = id % MARS_WORKLOAD_PER_BLOCK;
+
+ /* calculate block ea */
+ block_ea = get_block_ea(block);
+
+ /* notify host */
+ notify_host_bits(block_ea, index);
+
+ return MARS_SUCCESS;
}
static int host_signal_send(uint64_t watch_point_ea)
@@ -578,6 +639,8 @@ static struct mars_kernel_syscalls kernel_syscalls =
workload_signal_reset,
workload_schedule_begin,
workload_schedule_end,
+ workload_unschedule_begin,
+ workload_unschedule_end,
host_signal_send,
host_callback_set,
host_callback_reset,
@@ -807,29 +870,41 @@ static int workload_reserve(void)
static void workload_release(void)
{
+ int unscheduled;
int block = workload_id / MARS_WORKLOAD_PER_BLOCK;
int index = workload_id % MARS_WORKLOAD_PER_BLOCK;
uint64_t block_ea = get_block_ea(block);
-
- /* put the workload context into workload queue */
- dma_put(&workload, workload_ea,
- MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
- dma_wait(MARS_KERNEL_DMA_TAG);
+ uint8_t state;
/* lock the queue block */
mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
- /* update current workload state in workload queue block */
- MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_STATE, workload_state);
+ /* get current state */
+ state = MARS_BITS_GET(&queue_block.bits[index], WORKLOAD_STATE);
- /* update queue header bits */
- update_header_bits(block);
+ /* if state is unscheduling or finished, it (was/will be) aborted */
+ unscheduled = state & (MARS_WORKLOAD_STATE_UNSCHEDULING |
+ MARS_WORKLOAD_STATE_FINISHED);
+
+ if (!unscheduled) {
+ /* put the workload context into workload queue */
+ dma_put(&workload, workload_ea,
+ MARS_WORKLOAD_CONTEXT_SIZE, MARS_KERNEL_DMA_TAG);
+ dma_wait(MARS_KERNEL_DMA_TAG);
+
+ /* update current workload state in workload queue block */
+ MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_STATE,
+ workload_state);
+
+ /* update queue header bits */
+ update_header_bits(block);
+ }
/* unlock the queue block */
mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
/* workload state is finished so notify host */
- if (workload_state & MARS_WORKLOAD_STATE_FINISHED)
+ if (!unscheduled && (workload_state & MARS_WORKLOAD_STATE_FINISHED))
notify_host_bits(block_ea, index);
}
diff --git a/base/src/mpu/lib/module.S b/base/src/mpu/lib/module.S
index f6cb083..f6ab893 100644
--- a/base/src/mpu/lib/module.S
+++ b/base/src/mpu/lib/module.S
@@ -51,19 +51,21 @@
#define workload_signal_reset 44
#define workload_schedule_begin 48
#define workload_schedule_end 52
-#define host_signal_send 56
-#define host_callback_set 60
-#define host_callback_reset 64
-#define mutex_lock_get 68
-#define mutex_unlock_put 72
-#define dma_get 76
-#define dma_put 80
-#define dma_wait 84
+#define workload_unschedule_begin 56
+#define workload_unschedule_end 60
+#define host_signal_send 64
+#define host_callback_set 68
+#define host_callback_reset 72
+#define mutex_lock_get 76
+#define mutex_unlock_put 80
+#define dma_get 84
+#define dma_put 88
+#define dma_wait 92
/* NOTE: Value of defines must equal defines in workload_internal_types.h */
-#define WORKLOAD_EXIT_STATE_READY 0x08 /* MARS_WORKLOAD_STATE_READY */
-#define WORKLOAD_EXIT_STATE_WAITING 0x10 /* MARS_WORKLOAD_STATE_WAITING */
-#define WORKLOAD_EXIT_STATE_FINISHED 0x40 /* MARS_WORKLOAD_STATE_FINISHED */
+#define WORKLOAD_EXIT_STATE_READY 0x10 /* MARS_WORKLOAD_STATE_READY */
+#define WORKLOAD_EXIT_STATE_WAITING 0x20 /* MARS_WORKLOAD_STATE_WAITING */
+#define WORKLOAD_EXIT_STATE_FINISHED 0x80 /* MARS_WORKLOAD_STATE_FINISHED */
.section .bss
@@ -193,9 +195,8 @@ mars_module_workload_signal_reset:
.size mars_module_workload_signal_reset, .-mars_module_workload_signal_reset
-/* int mars_module_workload_schedule_begin(uint16_t id,
- uint8_t priority,
- struct mars_workload_context **workload) */
+/* int mars_module_workload_schedule_begin(uint16_t id, uint8_t priority,
+ struct mars_workload_context **workload) */
.global mars_module_workload_schedule_begin
.type mars_module_workload_schedule_begin, @function
mars_module_workload_schedule_begin:
@@ -213,6 +214,25 @@ mars_module_workload_schedule_end:
.size mars_module_workload_schedule_end, .-mars_module_workload_schedule_end
+/* int mars_module_workload_unschedule_begin(uint16_t id,
+ struct mars_workload_context **workload) */
+.global mars_module_workload_unschedule_begin
+.type mars_module_workload_unschedule_begin, @function
+mars_module_workload_unschedule_begin:
+ il $2, workload_unschedule_begin
+ br call_kernel_syscall
+.size mars_module_workload_unschedule_begin, .-mars_module_workload_unschedule_begin
+
+
+/* int mars_module_workload_unschedule_end(uint16_t id) */
+.global mars_module_workload_unschedule_end
+.type mars_module_workload_unschedule_end, @function
+mars_module_workload_unschedule_end:
+ il $2, workload_unschedule_end
+ br call_kernel_syscall
+.size mars_module_workload_unschedule_end, .-mars_module_workload_unschedule_end
+
+
/* void mars_module_workload_wait(void) */
.global mars_module_workload_wait
.type mars_module_workload_wait, @function