[Cbe-oss-dev] [PATCH 6/10] MARS: workload queue block use bit fields
Yuji Mano
Yuji.Mano at am.sony.com
Thu Aug 28 05:30:10 EST 2008
This patch changes the workload queue block structure to use a bitfield rather
than having separate arrays for each member and also allows us to specify
smaller sizes for members that don't need all 8-bits.
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
include/common/mars/mars_workload_types.h | 24 ++++++++----
src/host/lib/mars_workload_queue.c | 56 +++++++++++++++---------------
src/mpu/kernel/mars_kernel_scheduler.c | 51 ++++++++++++++-------------
src/mpu/kernel/mars_kernel_workload.c | 33 +++++++++--------
4 files changed, 89 insertions(+), 75 deletions(-)
--- a/include/common/mars/mars_workload_types.h
+++ b/include/common/mars/mars_workload_types.h
@@ -61,8 +61,8 @@ extern "C" {
#define MARS_WORKLOAD_COUNTER_MIN 0x0000 /* minimum counter */
#define MARS_WORKLOAD_COUNTER_MAX 0xffff /* maximum counter */
-#define MARS_WORKLOAD_SIGNAL_ON 1 /* signal set on */
-#define MARS_WORKLOAD_SIGNAL_OFF 0 /* signal set off */
+#define MARS_WORKLOAD_SIGNAL_ON 0x1 /* signal set on */
+#define MARS_WORKLOAD_SIGNAL_OFF 0x0 /* signal set off */
#define MARS_WORKLOAD_MAX 1024 /* wl max */
#define MARS_WORKLOAD_PER_BLOCK 16 /* wl per block */
@@ -70,9 +70,10 @@ extern "C" {
#define MARS_WORKLOAD_CONTEXT_SIZE 128 /* size of 128 bytes */
#define MARS_WORKLOAD_CONTEXT_ALIGN 128 /* align to 128 bytes */
+#define MARS_WORKLOAD_QUEUE_ALIGN 128 /* align to 128 bytes */
#define MARS_WORKLOAD_QUEUE_HEADER_ALIGN 128 /* align to 128 bytes */
#define MARS_WORKLOAD_QUEUE_BLOCK_ALIGN 128 /* align to 128 bytes */
-#define MARS_WORKLOAD_QUEUE_ALIGN 128 /* align to 128 bytes */
+#define MARS_WORKLOAD_QUEUE_BLOCK_BITS_ALIGN 8 /* align to 8 bytes */
/* mars workload context */
struct mars_workload_context {
@@ -87,14 +88,19 @@ struct mars_workload_queue_header {
uint8_t flag;
} __attribute__((aligned(MARS_WORKLOAD_QUEUE_HEADER_ALIGN)));
+/* 8 byte workload queue block bits structure */
+struct mars_workload_queue_block_bits {
+ uint64_t type:4;
+ uint64_t state:4;
+ uint64_t priority:8;
+ uint64_t signal:1;
+ uint64_t wait:16;
+ uint64_t counter:16;
+} __attribute__((aligned(MARS_WORKLOAD_QUEUE_BLOCK_BITS_ALIGN)));
+
/* 128 byte workload queue block structure */
struct mars_workload_queue_block {
- uint8_t type[MARS_WORKLOAD_PER_BLOCK];
- uint8_t state[MARS_WORKLOAD_PER_BLOCK];
- uint8_t priority[MARS_WORKLOAD_PER_BLOCK];
- uint16_t counter[MARS_WORKLOAD_PER_BLOCK];
- uint8_t signal[MARS_WORKLOAD_PER_BLOCK];
- uint16_t wait[MARS_WORKLOAD_PER_BLOCK];
+ struct mars_workload_queue_block_bits bits[MARS_WORKLOAD_PER_BLOCK];
} __attribute__((aligned(MARS_WORKLOAD_QUEUE_BLOCK_ALIGN)));
/* mars workload queue structure */
--- a/src/host/lib/mars_workload_queue.c
+++ b/src/host/lib/mars_workload_queue.c
@@ -88,7 +88,7 @@ int workload_queue_add(struct mars_workl
for (i = 0; i < MARS_WORKLOAD_NUM_BLOCKS; i++) {
for (j = 0; j < MARS_WORKLOAD_PER_BLOCK; j++) {
- if (queue->block[i].state[j] ==
+ if (queue->block[i].bits[j].state ==
MARS_WORKLOAD_STATE_NONE) {
block = i;
index = j;
@@ -107,12 +107,12 @@ int workload_queue_add(struct mars_workl
sizeof(struct mars_workload_context));
/* update workload queue header info */
- queue->block[block].type[index] = type;
- queue->block[block].state[index] = MARS_WORKLOAD_STATE_FINISHED;
- queue->block[block].priority[index] = MARS_WORKLOAD_PRIORITY_MIN;
- queue->block[block].counter[index] = MARS_WORKLOAD_COUNTER_MIN;
- queue->block[block].signal[index] = MARS_WORKLOAD_SIGNAL_OFF;
- queue->block[block].wait[index] = MARS_WORKLOAD_ID_NONE;
+ queue->block[block].bits[index].type = type;
+ queue->block[block].bits[index].state = MARS_WORKLOAD_STATE_FINISHED;
+ queue->block[block].bits[index].priority = MARS_WORKLOAD_PRIORITY_MIN;
+ queue->block[block].bits[index].counter = MARS_WORKLOAD_COUNTER_MIN;
+ queue->block[block].bits[index].signal = MARS_WORKLOAD_SIGNAL_OFF;
+ queue->block[block].bits[index].wait = MARS_WORKLOAD_ID_NONE;
queue->header.count++;
return MARS_SUCCESS;
@@ -128,7 +128,7 @@ int workload_queue_remove(struct mars_wo
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] ==
+ MARS_CHECK_RET(queue->block[block].bits[index].state ==
MARS_WORKLOAD_STATE_FINISHED, MARS_ERROR_STATE);
/* copy workload context out from workload queue */
@@ -136,12 +136,12 @@ int workload_queue_remove(struct mars_wo
sizeof(struct mars_workload_context));
/* update workload queue info */
- queue->block[block].type[index] = MARS_WORKLOAD_TYPE_NONE;
- queue->block[block].state[index] = MARS_WORKLOAD_STATE_NONE;
- queue->block[block].priority[index] = MARS_WORKLOAD_PRIORITY_MIN;
- queue->block[block].counter[index] = MARS_WORKLOAD_COUNTER_MIN;
- queue->block[block].signal[index] = MARS_WORKLOAD_SIGNAL_OFF;
- queue->block[block].wait[index] = MARS_WORKLOAD_ID_NONE;
+ queue->block[block].bits[index].type = MARS_WORKLOAD_TYPE_NONE;
+ queue->block[block].bits[index].state = MARS_WORKLOAD_STATE_NONE;
+ queue->block[block].bits[index].priority = MARS_WORKLOAD_PRIORITY_MIN;
+ queue->block[block].bits[index].counter = MARS_WORKLOAD_COUNTER_MIN;
+ queue->block[block].bits[index].signal = MARS_WORKLOAD_SIGNAL_OFF;
+ queue->block[block].bits[index].wait = MARS_WORKLOAD_ID_NONE;
queue->header.count--;
return MARS_SUCCESS;
@@ -157,7 +157,7 @@ int workload_queue_context(struct mars_w
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] !=
+ MARS_CHECK_RET(queue->block[block].bits[index].state !=
MARS_WORKLOAD_STATE_NONE, MARS_ERROR_STATE);
*workload = &queue->context[id];
@@ -174,14 +174,14 @@ int workload_queue_schedule(struct mars_
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] ==
+ MARS_CHECK_RET(queue->block[block].bits[index].state ==
MARS_WORKLOAD_STATE_FINISHED, MARS_ERROR_STATE);
- queue->block[block].state[index] = MARS_WORKLOAD_STATE_READY;
- queue->block[block].priority[index] = priority;
- queue->block[block].counter[index] = MARS_WORKLOAD_COUNTER_MIN;
- queue->block[block].signal[index] = MARS_WORKLOAD_SIGNAL_OFF;
- queue->block[block].wait[index] = MARS_WORKLOAD_ID_NONE;
+ queue->block[block].bits[index].state = MARS_WORKLOAD_STATE_READY;
+ queue->block[block].bits[index].priority = priority;
+ queue->block[block].bits[index].counter = MARS_WORKLOAD_COUNTER_MIN;
+ queue->block[block].bits[index].signal = MARS_WORKLOAD_SIGNAL_OFF;
+ queue->block[block].bits[index].wait = MARS_WORKLOAD_ID_NONE;
return MARS_SUCCESS;
}
@@ -194,10 +194,11 @@ int workload_queue_wait(struct mars_work
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] !=
+ MARS_CHECK_RET(queue->block[block].bits[index].state !=
MARS_WORKLOAD_STATE_NONE, MARS_ERROR_STATE);
- while (queue->block[block].state[index] != MARS_WORKLOAD_STATE_FINISHED)
+ while (queue->block[block].bits[index].state !=
+ MARS_WORKLOAD_STATE_FINISHED)
sched_yield();
return MARS_SUCCESS;
@@ -211,10 +212,11 @@ int workload_queue_try_wait(struct mars_
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] !=
+ MARS_CHECK_RET(queue->block[block].bits[index].state !=
MARS_WORKLOAD_STATE_NONE, MARS_ERROR_STATE);
- if (queue->block[block].state[index] != MARS_WORKLOAD_STATE_FINISHED)
+ if (queue->block[block].bits[index].state !=
+ MARS_WORKLOAD_STATE_FINISHED)
return MARS_ERROR_BUSY;
return MARS_SUCCESS;
@@ -228,10 +230,10 @@ int workload_queue_signal_send(struct ma
int block = id / MARS_WORKLOAD_PER_BLOCK;
int index = id % MARS_WORKLOAD_PER_BLOCK;
- MARS_CHECK_RET(queue->block[block].state[index] !=
+ MARS_CHECK_RET(queue->block[block].bits[index].state !=
MARS_WORKLOAD_STATE_NONE, MARS_ERROR_STATE);
- queue->block[block].signal[index] = MARS_WORKLOAD_SIGNAL_ON;
+ queue->block[block].bits[index].signal = MARS_WORKLOAD_SIGNAL_ON;
return MARS_SUCCESS;
}
--- a/src/mpu/kernel/mars_kernel_scheduler.c
+++ b/src/mpu/kernel/mars_kernel_scheduler.c
@@ -73,33 +73,34 @@ static int search_block(int block)
* and pick the workload that has been waiting the longest
*/
for (i = 0; i < MARS_WORKLOAD_PER_BLOCK; i++) {
- struct mars_workload_queue_block *p = &queue_block;
+ struct mars_workload_queue_block_bits *bits
+ = &queue_block.bits[i];
- switch (p->state[i]) {
+ switch (bits->state) {
case MARS_WORKLOAD_STATE_READY:
/* priority greater than max priority so select */
- if ((int)p->priority[i] > max_priority) {
+ if ((int)bits->priority > max_priority) {
index = i;
- max_count = p->counter[i];
- max_priority = p->priority[i];
+ max_count = bits->counter;
+ max_priority = bits->priority;
/* priority equal and wait counter greater so select */
- } else if ((int)p->priority[i] == max_priority &&
- (int)p->counter[i] > max_count) {
+ } else if ((int)bits->priority == max_priority &&
+ (int)bits->counter > max_count) {
index = i;
- max_count = p->counter[i];
+ max_count = bits->counter;
}
/* increment wait counter without overflowing */
- if (p->counter[i] < MARS_WORKLOAD_COUNTER_MAX)
- p->counter[i]++;
+ if (bits->counter < MARS_WORKLOAD_COUNTER_MAX)
+ bits->counter++;
break;
case MARS_WORKLOAD_STATE_WAITING:
/* waiting for workload to finish so check status */
- if (p->wait[i] != MARS_WORKLOAD_ID_NONE) {
+ if (bits->wait != MARS_WORKLOAD_ID_NONE) {
struct mars_workload_queue_block wait_block;
struct mars_workload_queue_block *p_wait_block;
- int bl = p->wait[i] / MARS_WORKLOAD_PER_BLOCK;
- int id = p->wait[i] % MARS_WORKLOAD_PER_BLOCK;
+ int bl = bits->wait / MARS_WORKLOAD_PER_BLOCK;
+ int id = bits->wait % MARS_WORKLOAD_PER_BLOCK;
/* check if workload id is in the same block */
if (block != bl) {
@@ -109,19 +110,19 @@ static int search_block(int block)
p_wait_block = &wait_block;
} else {
/* set pointer to check current block */
- p_wait_block = p;
+ p_wait_block = &queue_block;
}
/* check if workload is finished and reset */
- if (p_wait_block->state[id] ==
+ if (p_wait_block->bits[id].state ==
MARS_WORKLOAD_STATE_FINISHED) {
- p->wait[i] = MARS_WORKLOAD_ID_NONE;
- p->state[i] = MARS_WORKLOAD_STATE_READY;
+ bits->wait = MARS_WORKLOAD_ID_NONE;
+ bits->state = MARS_WORKLOAD_STATE_READY;
}
/* waiting for signal so check signal bit and reset */
- } else if (p->signal[i] == MARS_WORKLOAD_SIGNAL_ON) {
- p->signal[i] = MARS_WORKLOAD_SIGNAL_OFF;
- p->state[i] = MARS_WORKLOAD_STATE_READY;
+ } else if (bits->signal == MARS_WORKLOAD_SIGNAL_ON) {
+ bits->signal = MARS_WORKLOAD_SIGNAL_OFF;
+ bits->state = MARS_WORKLOAD_STATE_READY;
i--;
}
break;
@@ -153,10 +154,12 @@ static int reserve_block(int block)
index = search_block(block);
if (index >= 0) {
/* update the current state of the workload */
- queue_block.state[index] = MARS_WORKLOAD_STATE_RUNNING;
+ queue_block.bits[index].state =
+ MARS_WORKLOAD_STATE_RUNNING;
/* reset the counter for reserved workload */
- queue_block.counter[index] = MARS_WORKLOAD_COUNTER_MIN;
+ queue_block.bits[index].counter =
+ MARS_WORKLOAD_COUNTER_MIN;
}
/* attempt to write back workload queue block to cache line */
@@ -189,7 +192,7 @@ static void release_block(int block, int
sizeof(struct mars_workload_queue_block) * block);
/* update current workload state in workload queue block */
- queue_block.state[index] = workload_state;
+ queue_block.bits[index].state = workload_state;
/* attempt to write back workload queue block to cache line */
status = atomic_put(&queue_block,
@@ -223,7 +226,7 @@ int reserve_workload(void)
/* set global workload info based on workload block and index */
workload_index = MARS_WORKLOAD_PER_BLOCK * block + index;
- workload_type = queue_block.type[index];
+ workload_type = queue_block.bits[index].type;
workload_ea = queue_header.context_ea +
workload_index * sizeof(struct mars_workload_context);
--- a/src/mpu/kernel/mars_kernel_workload.c
+++ b/src/mpu/kernel/mars_kernel_workload.c
@@ -144,13 +144,14 @@ int workload_schedule(uint16_t workload_
sizeof(struct mars_workload_queue_block) * block);
/* make sure workload is in the correct state */
- if (queue_block.state[index] != MARS_WORKLOAD_STATE_FINISHED) {
+ if (queue_block.bits[index].state !=
+ MARS_WORKLOAD_STATE_FINISHED) {
atomic_event_restore();
return MARS_ERROR_STATE;
}
/* get information of workload to schedule */
- schedule_workload_type = queue_block.type[index];
+ schedule_workload_type = queue_block.bits[index].type;
schedule_workload_ea = queue_header.context_ea +
workload_id * sizeof(struct mars_workload_context);
@@ -175,11 +176,11 @@ int workload_schedule(uint16_t workload_
sizeof(struct mars_workload_context),
MARS_DMA_TAG);
- queue_block.state[index] = MARS_WORKLOAD_STATE_READY;
- queue_block.priority[index] = priority;
- queue_block.counter[index] = MARS_WORKLOAD_COUNTER_MIN;
- queue_block.signal[index] = MARS_WORKLOAD_SIGNAL_OFF;
- queue_block.wait[index] = MARS_WORKLOAD_ID_NONE;
+ queue_block.bits[index].state = MARS_WORKLOAD_STATE_READY;
+ queue_block.bits[index].priority = priority;
+ queue_block.bits[index].counter = MARS_WORKLOAD_COUNTER_MIN;
+ queue_block.bits[index].signal = MARS_WORKLOAD_SIGNAL_OFF;
+ queue_block.bits[index].wait = MARS_WORKLOAD_ID_NONE;
/* attempt to write back workload queue block to cache line */
status = atomic_put(&queue_block,
@@ -216,13 +217,13 @@ int workload_wait(uint16_t workload_id)
sizeof(struct mars_workload_queue_block) * block);
/* make sure workload is initialized */
- if (queue_block.state[index] == MARS_WORKLOAD_STATE_NONE) {
+ if (queue_block.bits[index].state == MARS_WORKLOAD_STATE_NONE) {
atomic_event_restore();
return MARS_ERROR_STATE;
}
/* set the workload id to wait for */
- queue_block.wait[index] = workload_id;
+ queue_block.bits[index].wait = workload_id;
/* attempt to write back workload queue block to cache line */
status = atomic_put(&queue_block,
@@ -253,10 +254,11 @@ int workload_try_wait(uint16_t workload_
offsetof(struct mars_workload_queue, block) +
sizeof(struct mars_workload_queue_block) * block);
- MARS_CHECK_RET(queue_block.state[index] != MARS_WORKLOAD_STATE_NONE,
+ MARS_CHECK_RET(queue_block.bits[index].state !=
+ MARS_WORKLOAD_STATE_NONE,
MARS_ERROR_STATE);
- if (queue_block.state[index] != MARS_WORKLOAD_STATE_FINISHED)
+ if (queue_block.bits[index].state != MARS_WORKLOAD_STATE_FINISHED)
return MARS_ERROR_BUSY;
return MARS_SUCCESS;
@@ -282,13 +284,13 @@ int workload_signal_send(uint16_t worklo
sizeof(struct mars_workload_queue_block) * block);
/* make sure workload is initialized */
- if (queue_block.state[index] == MARS_WORKLOAD_STATE_NONE) {
+ if (queue_block.bits[index].state == MARS_WORKLOAD_STATE_NONE) {
atomic_event_restore();
return MARS_ERROR_STATE;
}
/* set the workload signal */
- queue_block.signal[index] = MARS_WORKLOAD_SIGNAL_ON;
+ queue_block.bits[index].signal = MARS_WORKLOAD_SIGNAL_ON;
/* attempt to write back workload queue block to cache line */
status = atomic_put(&queue_block,
@@ -333,11 +335,12 @@ int workload_signal_try_wait(void)
offsetof(struct mars_workload_queue, block) +
sizeof(struct mars_workload_queue_block) * block);
- MARS_CHECK_RET(queue_block.state[index] != MARS_WORKLOAD_STATE_NONE,
+ MARS_CHECK_RET(queue_block.bits[index].state !=
+ MARS_WORKLOAD_STATE_NONE,
MARS_ERROR_STATE);
/* return busy if task has not received signal */
- if (queue_block.signal[index] != MARS_WORKLOAD_SIGNAL_ON)
+ if (queue_block.bits[index].signal != MARS_WORKLOAD_SIGNAL_ON)
return MARS_ERROR_BUSY;
return MARS_SUCCESS;
More information about the cbe-oss-dev
mailing list