[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