[Cbe-oss-dev] [PATCH 06/22]MARS/base: Module cleanup
Yuji Mano
yuji.mano at am.sony.com
Wed Jan 21 11:28:10 EST 2009
Clean up module api implementation to reduce duplicate code.
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
base/src/mpu/lib/module.c | 325 ++++++++++++++++++++--------------------------
1 file changed, 142 insertions(+), 183 deletions(-)
--- a/base/src/mpu/lib/module.c
+++ b/base/src/mpu/lib/module.c
@@ -52,6 +52,7 @@ static struct mars_workload_queue_header
static struct mars_workload_queue_block *queue_block;
static struct mars_workload_context schedule_workload;
static uint16_t schedule_workload_id;
+static uint64_t schedule_workload_ea;
void mars_module_entry(struct mars_kernel_syscalls *syscalls)
{
@@ -115,13 +116,9 @@ struct mars_workload_context *mars_modul
{
static struct mars_workload_context workload;
uint64_t workload_ea;
- uint16_t caller_id;
-
- /* get the id of the caller workload */
- caller_id = mars_module_get_workload_id();
/* id is caller workload's id so return current workload */
- if (id == caller_id)
+ if (id == mars_module_get_workload_id())
return mars_module_get_workload();
/* calculate workload ea */
@@ -135,12 +132,19 @@ struct mars_workload_context *mars_modul
return &workload;
}
-static uint64_t get_workload_bits(uint16_t id)
+static inline uint64_t get_block_ea(int block)
+{
+ return queue_header->queue_ea +
+ offsetof(struct mars_workload_queue, block) +
+ sizeof(struct mars_workload_queue_block) * block;
+}
+
+static uint64_t get_block_bits(uint16_t id)
{
int block;
int index;
uint64_t block_ea;
- uint64_t workload_bits;
+ uint64_t block_bits;
/* check function params */
if (id >= MARS_WORKLOAD_MAX)
@@ -151,196 +155,199 @@ static uint64_t get_workload_bits(uint16
index = id % MARS_WORKLOAD_PER_BLOCK;
/* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
+ block_ea = get_block_ea(block);
/* lock the queue block */
mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
- workload_bits = queue_block->bits[index];
+ block_bits = queue_block->bits[index];
/* unlock the queue block */
mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
- return workload_bits;
+ return block_bits;
}
int mars_module_workload_is_initialized(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_NONE);
}
int mars_module_workload_is_ready(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_READY);
}
int mars_module_workload_is_waiting(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_WAITING);
}
int mars_module_workload_is_running(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_RUNNING);
}
int mars_module_workload_is_finished(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_FINISHED);
}
int mars_module_workload_is_signal_set(uint16_t id)
{
- uint64_t bits = get_workload_bits(id);
+ uint64_t bits = get_block_bits(id);
return (MARS_BITS_GET(&bits, SIGNAL) == MARS_WORKLOAD_SIGNAL_ON);
}
-static void workload_wait_set(uint16_t id)
+static int change_bits(uint16_t id,
+ int (*check_bits)(uint64_t bits, uint64_t param),
+ uint64_t check_bits_param,
+ uint64_t (*set_bits)(uint64_t bits, uint64_t param),
+ uint64_t set_bits_param,
+ void (*callback)(uint16_t id))
{
int block;
int index;
uint64_t block_ea;
+ uint64_t bits;
+
+ /* check function params */
+ if (id >= MARS_WORKLOAD_MAX)
+ return MARS_ERROR_PARAMS;
/* calculate block/index from id */
- block = mars_module_get_workload_id() / MARS_WORKLOAD_PER_BLOCK;
- index = mars_module_get_workload_id() % MARS_WORKLOAD_PER_BLOCK;
+ block = id / MARS_WORKLOAD_PER_BLOCK;
+ index = id % MARS_WORKLOAD_PER_BLOCK;
/* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
+ block_ea = get_block_ea(block);
/* lock the queue block */
mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
- /* set the workload id to wait for */
- MARS_BITS_SET(&queue_block->bits[index], WAIT_ID, id);
+ /* check for valid state */
+ if (check_bits &&
+ !(*check_bits)(queue_block->bits[index], check_bits_param)) {
+ mars_mutex_unlock_put(block_ea,
+ (struct mars_mutex *)queue_block);
+ return MARS_ERROR_STATE;
+ }
- /* unlock the queue block */
- mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
-}
+ /* reset workload queue bits and set state to new state */
+ bits = (*set_bits)(queue_block->bits[index], set_bits_param);
-int mars_module_workload_wait_set(uint16_t id)
-{
- /* check function params */
- if (id >= MARS_WORKLOAD_MAX)
- return MARS_ERROR_PARAMS;
- if (id == mars_module_get_workload_id())
- return MARS_ERROR_PARAMS;
+ /* store new bits into queue block */
+ queue_block->bits[index] = bits;
+
+ /* if callback requested call it */
+ if (callback)
+ (*callback)(id);
- workload_wait_set(id);
+ /* unlock the queue block */
+ mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
return MARS_SUCCESS;
}
-int mars_module_workload_wait_reset(void)
+static int check_state_bits(uint64_t bits, uint64_t state)
{
- workload_wait_set(MARS_WORKLOAD_ID_NONE);
-
- return MARS_SUCCESS;
+ return (MARS_BITS_GET(&bits, STATE) == state);
}
-static void workload_signal_set(uint16_t id, uint8_t signal)
+static uint64_t set_state_bits(uint64_t bits, uint64_t state)
{
- int block;
- int index;
- uint64_t block_ea;
-
- /* calculate block/index from id */
- block = id / MARS_WORKLOAD_PER_BLOCK;
- index = id % MARS_WORKLOAD_PER_BLOCK;
-
- /* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
-
- /* lock the queue block */
- mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
+ MARS_BITS_SET(&bits, STATE, state);
- /* set the workload signal */
- MARS_BITS_SET(&queue_block->bits[index], SIGNAL, signal);
+ return bits;
+}
- /* unlock the queue block */
- mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
+static int change_state(uint16_t id,
+ unsigned int old_state,
+ unsigned int new_state,
+ void (*callback)(uint16_t id))
+{
+ return change_bits(id,
+ check_state_bits, old_state,
+ set_state_bits, new_state,
+ callback);
}
-int mars_module_workload_signal_set(uint16_t id)
+static uint64_t set_wait_id_bits(uint64_t bits, uint64_t id)
{
- uint16_t caller_id;
+ MARS_BITS_SET(&bits, WAIT_ID, id);
- /* get the id of the caller workload */
- caller_id = mars_module_get_workload_id();
+ return bits;
+}
- /* check function params */
- if (id >= MARS_WORKLOAD_MAX)
- return MARS_ERROR_PARAMS;
- if (id == caller_id)
+int mars_module_workload_wait_set(uint16_t id)
+{
+ if (id == mars_module_get_workload_id())
return MARS_ERROR_PARAMS;
- workload_signal_set(id, MARS_WORKLOAD_SIGNAL_ON);
-
- return MARS_SUCCESS;
+ return change_bits(mars_module_get_workload_id(),
+ NULL, 0,
+ set_wait_id_bits, id,
+ NULL);
}
-int mars_module_workload_signal_reset(void)
+int mars_module_workload_wait_reset(void)
{
- workload_signal_set(mars_module_get_workload_id(),
- MARS_WORKLOAD_SIGNAL_OFF);
-
- return MARS_SUCCESS;
+ return change_bits(mars_module_get_workload_id(),
+ NULL, 0,
+ set_wait_id_bits, MARS_WORKLOAD_ID_NONE,
+ NULL);
}
-int mars_module_workload_schedule_begin(uint16_t id, uint8_t priority,
- struct mars_workload_context **workload)
+static uint64_t set_signal_bits(uint64_t bits, uint64_t signal)
{
- int block;
- int index;
- uint64_t block_ea;
- uint64_t schedule_workload_ea;
- uint16_t caller_id;
+ MARS_BITS_SET(&bits, SIGNAL, signal);
- /* get the id of the caller workload */
- caller_id = mars_module_get_workload_id();
+ return bits;
+}
- /* check function params */
- if (id >= MARS_WORKLOAD_MAX)
- return MARS_ERROR_PARAMS;
- if (id == caller_id)
+int mars_module_workload_signal_set(uint16_t id)
+{
+ if (id == mars_module_get_workload_id())
return MARS_ERROR_PARAMS;
- /* calculate block/index from id */
- block = id / MARS_WORKLOAD_PER_BLOCK;
- index = id % MARS_WORKLOAD_PER_BLOCK;
+ return change_bits(id,
+ NULL, 0,
+ set_signal_bits, MARS_WORKLOAD_SIGNAL_ON,
+ NULL);
+}
- /* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
+int mars_module_workload_signal_reset(void)
+{
+ return change_bits(mars_module_get_workload_id(),
+ NULL, 0,
+ set_signal_bits, MARS_WORKLOAD_SIGNAL_OFF,
+ NULL);
+}
- mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
+static uint64_t set_schedule_bits(uint64_t bits, uint64_t priority)
+{
+ MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_SCHEDULING);
+ MARS_BITS_SET(&bits, PRIORITY, priority);
+ MARS_BITS_SET(&bits, COUNTER, MARS_WORKLOAD_COUNTER_MIN);
+ MARS_BITS_SET(&bits, SIGNAL, MARS_WORKLOAD_SIGNAL_OFF);
+ MARS_BITS_SET(&bits, WAIT_ID, MARS_WORKLOAD_ID_NONE);
- /* check for valid state */
- if (MARS_BITS_GET(&queue_block->bits[index], STATE) !=
- MARS_WORKLOAD_STATE_FINISHED) {
- mars_mutex_unlock_put(block_ea,
- (struct mars_mutex *)queue_block);
- return MARS_ERROR_STATE;
- }
+ return bits;
+}
+static void schedule_begin_callback(uint16_t id)
+{
/* get information of workload to schedule */
schedule_workload_id = id;
schedule_workload_ea = queue_header->context_ea +
@@ -349,20 +356,24 @@ int mars_module_workload_schedule_begin(
/* get the workload context from workload queue */
mars_dma_get_and_wait((void *)&schedule_workload, schedule_workload_ea,
sizeof(struct mars_workload_context), MARS_DMA_TAG);
+}
- /* initialize queue block bits */
- MARS_BITS_SET(&queue_block->bits[index], STATE,
- MARS_WORKLOAD_STATE_SCHEDULING);
- MARS_BITS_SET(&queue_block->bits[index], PRIORITY,
- priority);
- MARS_BITS_SET(&queue_block->bits[index], COUNTER,
- MARS_WORKLOAD_COUNTER_MIN);
- MARS_BITS_SET(&queue_block->bits[index], SIGNAL,
- MARS_WORKLOAD_SIGNAL_OFF);
- MARS_BITS_SET(&queue_block->bits[index], WAIT_ID,
- MARS_WORKLOAD_ID_NONE);
+int mars_module_workload_schedule_begin(uint16_t id, uint8_t priority,
+ struct mars_workload_context **workload)
+{
+ int ret;
- mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
+ /* check function params */
+ if (id == mars_module_get_workload_id())
+ return MARS_ERROR_PARAMS;
+
+ /* change bits necessary to begin scheduling */
+ ret = change_bits(id,
+ check_state_bits, MARS_WORKLOAD_STATE_FINISHED,
+ set_schedule_bits, priority,
+ schedule_begin_callback);
+ if (ret != MARS_SUCCESS)
+ return ret;
/* if requested set workload context pointer to return */
if (workload)
@@ -371,36 +382,8 @@ int mars_module_workload_schedule_begin(
return MARS_SUCCESS;
}
-int mars_module_workload_schedule_end(uint16_t id)
+static void schedule_end_callback(uint16_t id)
{
- int block;
- int index;
- uint64_t block_ea;
- uint64_t schedule_workload_ea;
-
- /* check function params */
- if (id != schedule_workload_id)
- return MARS_ERROR_PARAMS;
-
- /* calculate block/index from id */
- block = id / MARS_WORKLOAD_PER_BLOCK;
- index = id % MARS_WORKLOAD_PER_BLOCK;
-
- /* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
-
- mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
-
- /* check for valid state */
- if (MARS_BITS_GET(&queue_block->bits[index], STATE) !=
- MARS_WORKLOAD_STATE_SCHEDULING) {
- mars_mutex_unlock_put(block_ea,
- (struct mars_mutex *)queue_block);
- return MARS_ERROR_STATE;
- }
-
/* get information of workload to schedule */
schedule_workload_id = MARS_WORKLOAD_ID_NONE;
schedule_workload_ea = queue_header->context_ea +
@@ -409,52 +392,28 @@ int mars_module_workload_schedule_end(ui
/* put the workload context into workload queue */
mars_dma_put_and_wait((void *)&schedule_workload, schedule_workload_ea,
sizeof(struct mars_workload_context), MARS_DMA_TAG);
+}
- /* set state to ready */
- MARS_BITS_SET(&queue_block->bits[index], STATE,
- MARS_WORKLOAD_STATE_READY);
-
- mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
+int mars_module_workload_schedule_end(uint16_t id)
+{
+ if (id != schedule_workload_id)
+ return MARS_ERROR_PARAMS;
- return MARS_SUCCESS;
+ return change_state(id,
+ MARS_WORKLOAD_STATE_SCHEDULING,
+ MARS_WORKLOAD_STATE_READY,
+ schedule_end_callback);
}
int mars_module_workload_schedule_cancel(uint16_t id)
{
- int block;
- int index;
- uint64_t block_ea;
-
- /* check function params */
if (id != schedule_workload_id)
return MARS_ERROR_PARAMS;
- /* calculate block/index from id */
- block = id / MARS_WORKLOAD_PER_BLOCK;
- index = id % MARS_WORKLOAD_PER_BLOCK;
-
- /* calculate block ea */
- block_ea = queue_header->queue_ea +
- offsetof(struct mars_workload_queue, block) +
- sizeof(struct mars_workload_queue_block) * block;
-
- mars_mutex_lock_get(block_ea, (struct mars_mutex *)queue_block);
-
- /* check for valid state */
- if (MARS_BITS_GET(&queue_block->bits[index], STATE) !=
- MARS_WORKLOAD_STATE_SCHEDULING) {
- mars_mutex_unlock_put(block_ea,
- (struct mars_mutex *)queue_block);
- return MARS_ERROR_STATE;
- }
-
- /* set state back to finished */
- MARS_BITS_SET(&queue_block->bits[index], STATE,
- MARS_WORKLOAD_STATE_FINISHED);
-
- mars_mutex_unlock_put(block_ea, (struct mars_mutex *)queue_block);
-
- return MARS_SUCCESS;
+ return change_state(id,
+ MARS_WORKLOAD_STATE_SCHEDULING,
+ MARS_WORKLOAD_STATE_FINISHED,
+ NULL);
}
void mars_module_workload_wait(void)
More information about the cbe-oss-dev
mailing list