[Cbe-oss-dev] [PATCH 08/22]MARS/base: waiting block search fix
Yuji Mano
yuji.mano at am.sony.com
Fri Mar 20 07:54:10 EST 2009
From: Kazunori Asayama <asayama at sm.sony.co.jp>
Avoid block after processing waiting blocks.
The current scheduler has possibility to block forever after waiting
block is processed, since the static variable 'queue_header' is
overwritten in the 'update_header_bits' function. This patch fixes the
problem by retrying the search in that case.
This also reduces number of locks while processing waiting blocks.
Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
base/src/mpu/kernel/kernel.c | 63 +++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 28 deletions(-)
--- a/base/src/mpu/kernel/kernel.c
+++ b/base/src/mpu/kernel/kernel.c
@@ -704,8 +704,7 @@ static int search_block(int block, int r
MARS_BITS_SET(bits, WORKLOAD_STATE,
MARS_WORKLOAD_STATE_READY);
- /* update queue header bits */
- update_header_bits(block);
+ index = i;
}
/* waiting for signal so check signal bit and reset */
} else if (signal == MARS_WORKLOAD_SIGNAL_ON) {
@@ -714,37 +713,43 @@ static int search_block(int block, int r
MARS_BITS_SET(bits, WORKLOAD_STATE,
MARS_WORKLOAD_STATE_READY);
- /* update queue header bits */
- update_header_bits(block);
+ index = i;
}
}
}
/* index is set so reserve the runnable workload */
if (index >= 0) {
- /* update the current state of the workload */
- MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_STATE,
- MARS_WORKLOAD_STATE_RUNNING);
-
- /* reset the counter for reserved workload */
- MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_COUNTER,
- MARS_WORKLOAD_COUNTER_MIN);
-
- /* check if this kernel ran this workload most recently */
- workload_is_cached =
- (workload_id ==
- MARS_WORKLOAD_PER_BLOCK * block + index) &&
- (kernel_params.kernel_id ==
- MARS_BITS_GET(&queue_block.bits[index],
- WORKLOAD_KERNEL_ID));
-
- /* set the kernel id of this kernel into block bits */
- MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_KERNEL_ID,
- kernel_params.kernel_id);
+ if (ready) {
+ /* update the current state of the workload */
+ MARS_BITS_SET(&queue_block.bits[index],
+ WORKLOAD_STATE,
+ MARS_WORKLOAD_STATE_RUNNING);
+
+ /* reset the counter for reserved workload */
+ MARS_BITS_SET(&queue_block.bits[index],
+ WORKLOAD_COUNTER,
+ MARS_WORKLOAD_COUNTER_MIN);
+
+ /* check if kernel ran this workload most recently */
+ workload_is_cached =
+ (workload_id ==
+ MARS_WORKLOAD_PER_BLOCK * block + index) &&
+ (kernel_params.kernel_id ==
+ MARS_BITS_GET(&queue_block.bits[index],
+ WORKLOAD_KERNEL_ID));
+
+ /* set the kernel id of this kernel into block bits */
+ MARS_BITS_SET(&queue_block.bits[index],
+ WORKLOAD_KERNEL_ID,
+ kernel_params.kernel_id);
- /* update queue header bits and reset block counter */
+ /* reset block counter */
+ update_header_bits_counter(block, 1);
+ }
+
+ /* update queue header bits */
update_header_bits(block);
- update_header_bits_counter(block, 1);
}
/* unlock the queue block */
@@ -768,7 +773,8 @@ static int workload_reserve(void)
{
int i;
int block = -1;
- int index = -1;
+ int index;
+ int retry = 0;
uint8_t max_block_priority = 0;
uint16_t max_block_counter = 0;
@@ -806,12 +812,13 @@ static int workload_reserve(void)
/* block is waiting so check block */
if (block_waiting)
- search_block(i, 0);
+ retry |= (search_block(i, 0) >= 0);
}
/* no runnable workload found */
if (block < 0)
- return MARS_KERNEL_STATUS_IDLE;
+ return retry ?
+ MARS_KERNEL_STATUS_RETRY : MARS_KERNEL_STATUS_IDLE;
/* search block for workload index to run */
index = search_block(block, 1);
More information about the cbe-oss-dev
mailing list