[Cbe-oss-dev] [PATCH 13/17]MARS/modules/task: Separate ea from host

Yuji Mano yuji.mano at am.sony.com
Wed Nov 26 14:40:31 EST 2008


From: Kazunori Asayama <asayama at sm.sony.co.jp>

Separate EA space from host memory space (modules/task)

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
---
 modules/task/acinclude.m4                   |   26 ++++
 modules/task/src/host/lib/task.c            |   90 +++++++++++------
 modules/task/src/host/lib/task_barrier.c    |   20 ++-
 modules/task/src/host/lib/task_event_flag.c |  115 +++++++++++++++-------
 modules/task/src/host/lib/task_queue.c      |  146 +++++++++++++++++-----------
 modules/task/src/host/lib/task_semaphore.c  |   18 ++-
 6 files changed, 284 insertions(+), 131 deletions(-)

--- a/modules/task/acinclude.m4
+++ b/modules/task/acinclude.m4
@@ -56,6 +56,17 @@ AC_MSG_RESULT([using mars-platform ${wit
 ]) # AC_CONFIG_MARS_PLATFORM
 
 
+AC_DEFUN([AC_CONFIG_MARS_DISCRETE_SHARED_MEMORY],[
+AC_ARG_ENABLE(
+	[discrete-shared-memory],
+	[AS_HELP_STRING([--enable-discrete-shared-memory],
+		[assume discrete shared memory between host and MPU
+			even if shared memory is identical to host memory,
+			for debugging purposes])])
+AC_MSG_RESULT([using enable-discrete-shared-memory ${enable_discrete_shared_memory}])
+]) # AC_CONFIG_MARS_DISCRETE_SHARED_MEMORY
+
+
 AC_DEFUN([AC_CONFIG_DEBUG],[
 
 AC_ARG_ENABLE(
@@ -67,9 +78,24 @@ AC_MSG_RESULT([using enable-debug ${enab
 ]) # AC_CONFIG_DEBUG
 
 
+AC_DEFUN([AC_CONFIG_MARS_POST],[
+case "$with_mars_platform" in
+     spursengine) enable_discrete_shared_memory=yes;;
+esac
+
+if test "x$enable_discrete_shared_memory" = "xyes"; then
+	AC_DEFINE([MARS_ENABLE_DISCRETE_SHARED_MEMORY],[1],
+		[Define to 1 if shared memory between host and MPU is
+			separate from host memory.])
+fi
+])
+
+
 AC_DEFUN([AC_CONFIG_MARS],[
 
 AC_CONFIG_MARS_PLATFORM
+AC_CONFIG_MARS_DISCRETE_SHARED_MEMORY
 AC_CONFIG_DEBUG
+AC_CONFIG_MARS_POST
 
 ]) # AC_CONFIG_MARS
--- a/modules/task/src/host/lib/task.c
+++ b/modules/task/src/host/lib/task.c
@@ -58,6 +58,11 @@ const struct mars_task_context_save_unit
 	{ .addr = 0, .size = 0 },
 };
 
+static uint64_t task_exit_code_ea(uint64_t task_ea)
+{
+	return task_ea + offsetof(struct mars_task_context, exit_code);
+}
+
 int mars_task_create(struct mars_context *mars,
 		struct mars_task_id *id_ret,
 		const char *name, const void *elf_image,
@@ -105,20 +110,31 @@ int mars_task_create(struct mars_context
 	if (ret != MARS_SUCCESS)
 		return ret;
 
-	/* cast workload context to task context */
-	task = mars_ea_to_ptr(workload_ea);
+	/* prepare work area for task context */
+	task = mars_ea_work_area_get(workload_ea,
+		MARS_TASK_CONTEXT_ALIGN, MARS_TASK_CONTEXT_SIZE);
 
 	/* initialize the module elf parameters */
-	task->module.exec_ea =
-		mars_ptr_to_ea((void *)ehdr_module + phdr_module->p_offset);
 	task->module.exec_size = phdr_module->p_filesz;
+	task->module.exec_ea =
+		mars_ea_map((void *)ehdr_module + phdr_module->p_offset,
+			task->module.exec_size);
+	if (!task->module.exec_ea) {
+		ret = MARS_ERROR_MEMORY;
+		goto error_map_module;
+	}
 	task->module.bss_size = phdr_module->p_memsz - phdr_module->p_filesz;
 	task->module.entry = ehdr_module->e_entry;
 
 	/* initialize the task elf parameters */
-	task->exec_ea =
-		mars_ptr_to_ea((void *)ehdr_task + phdr_task->p_offset);
 	task->exec_size = phdr_task->p_filesz;
+	task->exec_ea =
+		mars_ea_map((void *)ehdr_task + phdr_task->p_offset,
+			    task->exec_size);
+	if (!task->exec_ea) {
+		ret = MARS_ERROR_MEMORY;
+		goto error_map_exec;
+	}
 	task->bss_size = phdr_task->p_memsz - phdr_task->p_filesz;
 	task->vaddr = phdr_task->p_vaddr;
 	task->entry = ehdr_task->e_entry;
@@ -155,28 +171,32 @@ int mars_task_create(struct mars_context
 	}
 
 	/* allocate context save unit storage */
-	task->context_save_unit_ea = mars_ptr_to_ea(mars_ea_memalign(
+	task->context_save_unit_ea = mars_ea_memalign(
 		MARS_TASK_CONTEXT_SAVE_UNIT_ALIGN,
-		context_save_unit_count * MARS_TASK_CONTEXT_SAVE_UNIT_SIZE));
+		context_save_unit_count * MARS_TASK_CONTEXT_SAVE_UNIT_SIZE);
 	if (!task->context_save_unit_ea) {
 		ret = MARS_ERROR_MEMORY;
 		goto error_malloc_context_save_unit;
 	}
 
 	/* allocate context save area */
-	task->context_save_area_ea = mars_ptr_to_ea(mars_ea_memalign(
-		MARS_TASK_CONTEXT_SAVE_ALIGN, context_save_area_size));
+	task->context_save_area_ea = mars_ea_memalign(
+		MARS_TASK_CONTEXT_SAVE_ALIGN, context_save_area_size);
 	if (!task->context_save_area_ea) {
 		ret = MARS_ERROR_MEMORY;
 		goto error_malloc_context_save_area;
 	}
 
 	/* copy the context save struct into allocated storage */
-	memcpy(mars_ea_to_ptr(task->context_save_unit_ea),
+	mars_ea_put(task->context_save_unit_ea,
 		context_save_unit,
 		context_save_unit_count * MARS_TASK_CONTEXT_SAVE_UNIT_SIZE);
 
 done:
+	/* update task context on EA */
+	mars_ea_put(workload_ea, task, MARS_TASK_CONTEXT_SIZE);
+	mars_ea_sync();
+
 	/* end process to add the task to the workload queue */
 	ret = mars_workload_queue_add_end(mars, workload_id);
 	if (ret != MARS_SUCCESS)
@@ -188,11 +208,15 @@ done:
 	return MARS_SUCCESS;
 
 error_workload_queue_add_end:
-	mars_ea_free(mars_ea_to_ptr(task->context_save_area_ea));
+	mars_ea_free(task->context_save_area_ea);
 error_malloc_context_save_area:
-	mars_ea_free(mars_ea_to_ptr(task->context_save_unit_ea));
+	mars_ea_free(task->context_save_unit_ea);
 error_malloc_context_save_unit:
 error_context_save_unit_addr_align:
+	mars_ea_unmap(task->exec_ea, task->exec_size);
+error_map_exec:
+	mars_ea_unmap(task->module.exec_ea, task->module.exec_size);
+error_map_module:
 	mars_workload_queue_add_cancel(mars, workload_id);
 
 	return ret;
@@ -220,16 +244,24 @@ int mars_task_destroy(struct mars_task_i
 	if (ret != MARS_SUCCESS)
 		return ret;
 
-	/* cast workload context to task context */
-	task = mars_ea_to_ptr(workload_ea);
+	/* prepare work area for task context */
+	task = mars_ea_work_area_get(workload_ea,
+		MARS_TASK_CONTEXT_ALIGN, MARS_TASK_CONTEXT_SIZE);
+
+	/* get task context from EA */
+	mars_ea_get(workload_ea, task, MARS_TASK_CONTEXT_SIZE);
 
 	/* free the allocated context save area if it has one */
 	if (task->context_save_area_ea)
-		mars_ea_free(mars_ea_to_ptr(task->context_save_area_ea));
+		mars_ea_free(task->context_save_area_ea);
 
 	/* free the allocated context save unit storage if it has one */
 	if (task->context_save_unit_ea)
-		mars_ea_free(mars_ea_to_ptr(task->context_save_unit_ea));
+		mars_ea_free(task->context_save_unit_ea);
+
+	/* unmap ELFs */
+	mars_ea_unmap(task->module.exec_ea, task->module.exec_size);
+	mars_ea_unmap(task->exec_ea, task->exec_size);
 
 	/* end process to remove the task from the workload queue */
 	ret = mars_workload_queue_remove_end(mars, id->workload_id);
@@ -262,14 +294,22 @@ int mars_task_schedule(struct mars_task_
 	if (ret != MARS_SUCCESS)
 		return ret;
 
-	/* cast workload context to task context */
-	task = mars_ea_to_ptr(workload_ea);
+	/* prepare work area for task context */
+	task = mars_ea_work_area_get(workload_ea,
+		MARS_TASK_CONTEXT_ALIGN, MARS_TASK_CONTEXT_SIZE);
+
+	/* get task context from EA */
+	mars_ea_get(workload_ea, task, MARS_TASK_CONTEXT_SIZE);
 
 	/* initialize task specific context variables */
 	task->stack = 0;
 	if (args)
 		memcpy(&task->args, args, sizeof(struct mars_task_args));
 
+	/* update task context on EA */
+	mars_ea_put(workload_ea, task, MARS_TASK_CONTEXT_SIZE);
+	mars_ea_sync();
+
 	/* end process to schedule the workload in the workload queue */
 	ret = mars_workload_queue_schedule_end(mars, id->workload_id);
 	if (ret != MARS_SUCCESS)
@@ -282,7 +322,6 @@ int mars_task_wait(struct mars_task_id *
 {
 	int ret;
 	struct mars_context *mars;
-	struct mars_task_context *task;
 	uint64_t workload_ea;
 
 	/* check function params */
@@ -299,12 +338,9 @@ int mars_task_wait(struct mars_task_id *
 	if (ret != MARS_SUCCESS)
 		return ret;
 
-	/* cast workload context to task context */
-	task = mars_ea_to_ptr(workload_ea);
-
 	/* exit_code requested so return it to caller */
 	if (exit_code)
-		*exit_code = task->exit_code;
+		*exit_code = mars_ea_get_uint32(task_exit_code_ea(workload_ea));
 
 	return MARS_SUCCESS;
 }
@@ -313,7 +349,6 @@ int mars_task_try_wait(struct mars_task_
 {
 	int ret;
 	struct mars_context *mars;
-	struct mars_task_context *task;
 	uint64_t workload_ea;
 
 	/* check function params */
@@ -330,12 +365,9 @@ int mars_task_try_wait(struct mars_task_
 	if (ret != MARS_SUCCESS)
 		return ret;
 
-	/* cast workload context to task context */
-	task = mars_ea_to_ptr(workload_ea);
-
 	/* exit_code requested so return it to caller */
 	if (exit_code)
-		*exit_code = task->exit_code;
+		*exit_code = mars_ea_get_uint32(task_exit_code_ea(workload_ea));
 
 	return MARS_SUCCESS;
 }
--- a/modules/task/src/host/lib/task_barrier.c
+++ b/modules/task/src/host/lib/task_barrier.c
@@ -61,16 +61,16 @@ int mars_task_barrier_create(struct mars
 		return MARS_ERROR_PARAMS;
 
 	/* allocate barrier instance */
-	barrier = (struct mars_task_barrier *)mars_ea_memalign(
+	barrier_ea = mars_ea_memalign(
 		MARS_TASK_BARRIER_ALIGN, MARS_TASK_BARRIER_SIZE);
-	if (!barrier)
+	if (!barrier_ea)
 		return MARS_ERROR_MEMORY;
 
-	barrier_ea = mars_ptr_to_ea(barrier);
-
-	mars_mutex_reset(barrier_ea);
+	/* prepare work area for initialization */
+	barrier = mars_ea_work_area_get(barrier_ea,
+		MARS_TASK_BARRIER_ALIGN, MARS_TASK_BARRIER_SIZE);
 
-	/* initialize barrier instance */
+	/* initialize barrier instance on work area */
 	barrier->mars_context_ea = mars_ptr_to_ea(mars);
 	barrier->total = total;
 	barrier->notified_count = 0;
@@ -78,6 +78,12 @@ int mars_task_barrier_create(struct mars
 	barrier->notify_wait_count = 0;
 	barrier->wait_count = 0;
 
+	/* update barrier on EA */
+	mars_ea_put(barrier_ea, barrier, MARS_TASK_BARRIER_SIZE);
+	mars_ea_sync();
+
+	mars_mutex_reset(barrier_ea);
+
 	/* return barrier instance pointer */
 	*barrier_ea_ret = barrier_ea;
 
@@ -90,7 +96,7 @@ int mars_task_barrier_destroy(uint64_t b
 	if (!barrier_ea)
 		return MARS_ERROR_NULL;
 
-	mars_ea_free(mars_ea_to_ptr(barrier_ea));
+	mars_ea_free(barrier_ea);
 
 	return MARS_SUCCESS;
 }
--- a/modules/task/src/host/lib/task_event_flag.c
+++ b/modules/task/src/host/lib/task_event_flag.c
@@ -50,6 +50,13 @@
 
 #include "task_event_flag_internal_types.h"
 
+
+static inline uint64_t event_flag_bits_ea(uint64_t event_flag_ea)
+{
+	return event_flag_ea +
+		offsetof(struct mars_task_event_flag, bits);
+}
+
 int mars_task_event_flag_create(struct mars_context *mars,
 				uint64_t *event_flag_ea_ret,
 				uint8_t direction,
@@ -72,22 +79,28 @@ int mars_task_event_flag_create(struct m
 		return MARS_ERROR_PARAMS;
 
 	/* allocate event flag instance */
-	event_flag = (struct mars_task_event_flag *)mars_ea_memalign(
+	event_flag_ea = mars_ea_memalign(
 		MARS_TASK_EVENT_FLAG_ALIGN, MARS_TASK_EVENT_FLAG_SIZE);
-	if (!event_flag)
+	if (!event_flag_ea)
 		return MARS_ERROR_MEMORY;
 
-	event_flag_ea = mars_ptr_to_ea(event_flag);
-
-	mars_mutex_reset(event_flag_ea);
+	/* prepare work area for initialization */
+	event_flag = mars_ea_work_area_get(event_flag_ea,
+		MARS_TASK_EVENT_FLAG_ALIGN, MARS_TASK_EVENT_FLAG_SIZE);
 
-	/* intialize event flag instance */
+	/* intialize event flag instance on work area */
 	event_flag->mars_context_ea = mars_ptr_to_ea(mars);
 	event_flag->bits = 0;
 	event_flag->direction = direction;
 	event_flag->clear_mode = clear_mode;
 	event_flag->wait_count = 0;
 
+	/* update event flag on EA */
+	mars_ea_put(event_flag_ea, event_flag, MARS_TASK_EVENT_FLAG_SIZE);
+	mars_ea_sync();
+
+	mars_mutex_reset(event_flag_ea);
+
 	/* return event flag instance pointer */
 	*event_flag_ea_ret = event_flag_ea;
 
@@ -100,23 +113,26 @@ int mars_task_event_flag_destroy(uint64_
 	if (!event_flag_ea)
 		return MARS_ERROR_NULL;
 
-	mars_ea_free(mars_ea_to_ptr(event_flag_ea));
+	mars_ea_free(event_flag_ea);
 
 	return MARS_SUCCESS;
 }
 
 int mars_task_event_flag_clear(uint64_t event_flag_ea, uint32_t bits)
 {
-	struct mars_task_event_flag *event_flag =
-		mars_ea_to_ptr(event_flag_ea);
+	uint32_t new_bits;
+	uint64_t bits_ea;
 
 	if (!event_flag_ea)
 		return MARS_ERROR_NULL;
 
+	bits_ea = event_flag_bits_ea(event_flag_ea);
+
 	mars_mutex_lock(event_flag_ea);
 
 	/* clear the necessary bits */
-	event_flag->bits &= ~bits;
+	new_bits = mars_ea_get_uint32(bits_ea) & ~bits;
+	mars_ea_put_uint32(bits_ea, new_bits);
 
 	mars_mutex_unlock(event_flag_ea);
 
@@ -128,18 +144,26 @@ int mars_task_event_flag_set(uint64_t ev
 	int ret;
 	int i;
 	struct mars_context *mars;
-	struct mars_task_event_flag *event_flag =
-		mars_ea_to_ptr(event_flag_ea);
+	struct mars_task_event_flag *event_flag;
 
 	/* check function params */
-	if (!event_flag)
+	if (!event_flag_ea)
 		return MARS_ERROR_NULL;
+
+	/* prepare work area */
+	event_flag = mars_ea_work_area_get(event_flag_ea,
+		MARS_TASK_EVENT_FLAG_ALIGN, MARS_TASK_EVENT_FLAG_SIZE);
+
+	/* get event flag from EA */
+	mars_mutex_lock_get(event_flag_ea, (struct mars_mutex *)event_flag);
+
+	/* check event flag status */
+	ret = MARS_ERROR_NULL;
 	if (!event_flag->mars_context_ea)
-		return MARS_ERROR_NULL;
+		goto end;
+	ret = MARS_ERROR_STATE;
 	if (event_flag->direction != MARS_TASK_EVENT_FLAG_HOST_TO_MPU)
-		return MARS_ERROR_STATE;
-
-	mars_mutex_lock(event_flag_ea);
+		goto end;
 
 	/* get mars context pointer */
 	mars = mars_ea_to_ptr(event_flag->mars_context_ea);
@@ -169,7 +193,7 @@ int mars_task_event_flag_set(uint64_t ev
 		ret = mars_workload_queue_signal_send(mars,
 			event_flag->wait_id[i]);
 		if (ret != MARS_SUCCESS)
-			return ret;
+			goto end;
 
 		/* flush id from wait list */
 		event_flag->wait_count--;
@@ -185,58 +209,76 @@ int mars_task_event_flag_set(uint64_t ev
 		i--;
 	}
 
-	mars_mutex_unlock(event_flag_ea);
+	ret = MARS_SUCCESS;
 
-	return MARS_SUCCESS;
+end:
+	mars_mutex_unlock_put(event_flag_ea, (struct mars_mutex *)event_flag);
+
+	return ret;
 }
 
 static int wait(uint64_t event_flag_ea,
 		uint32_t mask, uint8_t mask_mode, uint32_t *bits, int try)
 {
-	struct mars_task_event_flag *event_flag =
-		mars_ea_to_ptr(event_flag_ea);
+	int ret;
+	struct mars_task_event_flag *event_flag;
+	uint64_t bits_ea;
 
 	/* check function params */
-	if (!event_flag)
+	if (!event_flag_ea)
 		return MARS_ERROR_NULL;
+
+	/* prepare work area */
+	event_flag = mars_ea_work_area_get(event_flag_ea,
+		MARS_TASK_EVENT_FLAG_ALIGN, MARS_TASK_EVENT_FLAG_SIZE);
+
+	/* get event flag from EA */
+	mars_mutex_lock_get(event_flag_ea, (struct mars_mutex *)event_flag);
+
+	/* check function params */
+	ret = MARS_ERROR_STATE;
 	if (event_flag->direction != MARS_TASK_EVENT_FLAG_MPU_TO_HOST)
-		return MARS_ERROR_STATE;
+		goto end;
+	ret = MARS_ERROR_PARAMS;
 	if (mask_mode != MARS_TASK_EVENT_FLAG_MASK_OR &&
 		mask_mode != MARS_TASK_EVENT_FLAG_MASK_AND)
-		return MARS_ERROR_PARAMS;
-
-	mars_mutex_lock(event_flag_ea);
+		goto end;
 
 	/* check condition based on wait mode */
+	bits_ea = event_flag_bits_ea(event_flag_ea);
 	switch (mask_mode) {
 	case MARS_TASK_EVENT_FLAG_MASK_OR:
 		while ((event_flag->bits & mask) == 0) {
-			mars_mutex_unlock(event_flag_ea);
+			mars_mutex_unlock_put(event_flag_ea,
+					      (struct mars_mutex *)event_flag);
 
 			/* only try so return busy */
 			if (try)
 				return MARS_ERROR_BUSY;
 
 			/* yield until condition is met */
-			while ((event_flag->bits & mask) == 0)
+			while ((mars_ea_get_uint32(bits_ea) & mask) == 0)
 				sched_yield();
 
-			mars_mutex_lock(event_flag_ea);
+			mars_mutex_lock_get(event_flag_ea,
+					    (struct mars_mutex *)event_flag);
 		}
 		break;
 	case MARS_TASK_EVENT_FLAG_MASK_AND:
 		while ((event_flag->bits & mask) != mask) {
-			mars_mutex_unlock(event_flag_ea);
+			mars_mutex_unlock_put(event_flag_ea,
+					      (struct mars_mutex *)event_flag);
 
 			/* only try so return busy */
 			if (try)
 				return MARS_ERROR_BUSY;
 
 			/* yield until condition is met */
-			while ((event_flag->bits & mask) != mask)
+			while ((mars_ea_get_uint32(bits_ea) & mask) != mask)
 				sched_yield();
 
-			mars_mutex_lock(event_flag_ea);
+			mars_mutex_lock_get(event_flag_ea,
+					    (struct mars_mutex *)event_flag);
 		}
 		break;
 	}
@@ -249,9 +291,12 @@ static int wait(uint64_t event_flag_ea,
 	if (event_flag->clear_mode == MARS_TASK_EVENT_FLAG_CLEAR_AUTO)
 		event_flag->bits &= ~mask;
 
-	mars_mutex_unlock(event_flag_ea);
+	ret = MARS_SUCCESS;
 
-	return MARS_SUCCESS;
+end:
+	mars_mutex_unlock_put(event_flag_ea, (struct mars_mutex *)event_flag);
+
+	return ret;
 }
 
 int mars_task_event_flag_wait(uint64_t event_flag_ea,
--- a/modules/task/src/host/lib/task_queue.c
+++ b/modules/task/src/host/lib/task_queue.c
@@ -50,6 +50,11 @@
 
 #include "task_queue_internal_types.h"
 
+static inline uint64_t queue_count_ea(uint64_t queue_ea)
+{
+	return queue_ea + offsetof(struct mars_task_queue, count);
+}
+
 int mars_task_queue_create(struct mars_context *mars,
 				uint64_t *queue_ea_ret,
 				uint32_t size,
@@ -58,7 +63,7 @@ int mars_task_queue_create(struct mars_c
 {
 	struct mars_task_queue *queue;
 	uint64_t queue_ea;
-	void *buffer;
+	uint64_t buffer_ea;
 
 	/* check function params */
 	if (!mars)
@@ -75,25 +80,27 @@ int mars_task_queue_create(struct mars_c
 		return MARS_ERROR_PARAMS;
 
 	/* allocate queue instance */
-	queue = (struct mars_task_queue *)mars_ea_memalign(
+	queue_ea = mars_ea_memalign(
 		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_MEMORY;
 
-	queue_ea = mars_ptr_to_ea(queue);
+	/* prepare work area for initialization */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
 
 	/* allocate queue buffer instance */
-	buffer = mars_ea_memalign(MARS_TASK_QUEUE_BUFFER_ALIGN, size * depth);
-	if (!buffer)
+	buffer_ea = mars_ea_memalign(MARS_TASK_QUEUE_BUFFER_ALIGN, size * depth);
+	if (!buffer_ea) {
+		mars_ea_free(queue_ea);
 		return MARS_ERROR_MEMORY;
-
-	mars_mutex_reset(queue_ea);
+	}
 
 	/* initialize queue instance */
 	queue->mars_context_ea = mars_ptr_to_ea(mars);
-	queue->buffer_ea = mars_ptr_to_ea(buffer);
-	queue->push_ea = mars_ptr_to_ea(buffer);
-	queue->pop_ea = mars_ptr_to_ea(buffer);
+	queue->buffer_ea = buffer_ea;
+	queue->push_ea = buffer_ea;
+	queue->pop_ea = buffer_ea;
 	queue->size = size;
 	queue->depth = depth;
 	queue->direction = direction;
@@ -101,6 +108,12 @@ int mars_task_queue_create(struct mars_c
 	queue->push_wait_count = 0;
 	queue->pop_wait_count = 0;
 
+	/* update queue on EA */
+	mars_ea_put(queue_ea, queue, MARS_TASK_QUEUE_SIZE);
+	mars_ea_sync();
+
+	mars_mutex_reset(queue_ea);
+
 	/* return queue instance pointer */
 	*queue_ea_ret = queue_ea;
 
@@ -109,36 +122,40 @@ int mars_task_queue_create(struct mars_c
 
 int mars_task_queue_destroy(uint64_t queue_ea)
 {
-	struct mars_task_queue *queue =
-		mars_ea_to_ptr(queue_ea);
+	struct mars_task_queue *queue;
 
 	/* check function params */
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_NULL;
 
-	mars_ea_free(mars_ea_to_ptr(queue->buffer_ea));
-	mars_ea_free(queue);
+	/* prepare work area */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
+
+	mars_ea_get(queue_ea, queue, MARS_TASK_QUEUE_SIZE);
+
+	/* free shared memory */
+	mars_ea_free(queue->buffer_ea);
+	mars_ea_free(queue_ea);
 
 	return MARS_SUCCESS;
 }
 
 int mars_task_queue_count(uint64_t queue_ea, uint32_t *count)
 {
-	struct mars_task_queue *queue =
-		mars_ea_to_ptr(queue_ea);
-
 	/* check function params */
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_NULL;
 	if (!count)
 		return MARS_ERROR_NULL;
-	if ((uintptr_t)queue & MARS_TASK_QUEUE_ALIGN_MASK)
+	if (queue_ea & MARS_TASK_QUEUE_ALIGN_MASK)
 		return MARS_ERROR_ALIGN;
 
+	/* get queue from EA */
 	mars_mutex_lock(queue_ea);
 
 	/* return current items in queue */
-	*count = queue->count;
+	*count = mars_ea_get_uint32(queue_count_ea(queue_ea));
 
 	mars_mutex_unlock(queue_ea);
 
@@ -149,16 +166,19 @@ int mars_task_queue_clear(uint64_t queue
 {
 	int i;
 	struct mars_context *mars;
-	struct mars_task_queue *queue =
-		mars_ea_to_ptr(queue_ea);
+	struct mars_task_queue *queue;
 
 	/* check function params */
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_NULL;
-	if ((uintptr_t)queue & MARS_TASK_QUEUE_ALIGN_MASK)
+	if (queue_ea & MARS_TASK_QUEUE_ALIGN_MASK)
 		return MARS_ERROR_ALIGN;
 
-	mars_mutex_lock(queue_ea);
+	/* prepare work area */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
+
+	mars_mutex_lock_get(queue_ea, (struct mars_mutex *)queue);
 
 	/* get mars context pointer */
 	mars = mars_ea_to_ptr(queue->mars_context_ea);
@@ -175,7 +195,7 @@ int mars_task_queue_clear(uint64_t queue
 	queue->push_ea = queue->buffer_ea;
 	queue->pop_ea = queue->buffer_ea;
 
-	mars_mutex_unlock(queue_ea);
+	mars_mutex_unlock_put(queue_ea, (struct mars_mutex *)queue);
 
 	return MARS_SUCCESS;
 }
@@ -208,42 +228,52 @@ static void push_update(struct mars_task
 
 static int push(uint64_t queue_ea, const void *data, int try)
 {
-	struct mars_task_queue *queue =
-		mars_ea_to_ptr(queue_ea);
+	int ret;
+	struct mars_task_queue *queue;
 
 	/* check function params */
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_NULL;
-	if ((uintptr_t)queue & MARS_TASK_QUEUE_ALIGN_MASK)
+	if (queue_ea & MARS_TASK_QUEUE_ALIGN_MASK)
 		return MARS_ERROR_ALIGN;
-	if (queue->direction != MARS_TASK_QUEUE_HOST_TO_MPU)
-		return MARS_ERROR_STATE;
 
-	mars_mutex_lock(queue_ea);
+	/* prepare work area */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
+
+	mars_mutex_lock_get(queue_ea, (struct mars_mutex *)queue);
+
+	/* check queue status */
+	ret = MARS_ERROR_STATE;
+	if (queue->direction != MARS_TASK_QUEUE_HOST_TO_MPU)
+		goto end;
 
 	/* queue is full so wait */
 	while (queue->count == queue->depth) {
-		mars_mutex_unlock(queue_ea);
+		mars_mutex_unlock_put(queue_ea, (struct mars_mutex *)queue);
 
 		/* only try so return busy */
 		if (try)
 			return MARS_ERROR_BUSY;
 
-		while (queue->count == queue->depth)
+		while (mars_ea_get_uint32(queue_count_ea(queue_ea)) ==
+		       queue->depth)
 			sched_yield();
 
-		mars_mutex_lock(queue_ea);
+		mars_mutex_lock_get(queue_ea, (struct mars_mutex *)queue);
 	}
 
 	/* copy data into queue */
-	memcpy(mars_ea_to_ptr(queue->push_ea), data, queue->size);
+	mars_ea_put(queue->push_ea, data, queue->size);
 
 	/* update queue data */
 	push_update(queue);
 
-	mars_mutex_unlock(queue_ea);
+	ret = MARS_SUCCESS;
+end:
+	mars_mutex_unlock_put(queue_ea, (struct mars_mutex*)queue);
 
-	return MARS_SUCCESS;
+	return ret;
 }
 
 int mars_task_queue_push(uint64_t queue_ea, const void *data)
@@ -284,43 +314,51 @@ static void pop_update(struct mars_task_
 
 static int pop(uint64_t queue_ea, void *data, int peek, int try)
 {
-	struct mars_task_queue *queue =
-		mars_ea_to_ptr(queue_ea);
+	int ret;
+	struct mars_task_queue *queue;
 
 	/* check function params */
-	if (!queue)
+	if (!queue_ea)
 		return MARS_ERROR_NULL;
-	if ((uintptr_t)queue & MARS_TASK_QUEUE_ALIGN_MASK)
+	if (queue_ea & MARS_TASK_QUEUE_ALIGN_MASK)
 		return MARS_ERROR_ALIGN;
-	if (queue->direction != MARS_TASK_QUEUE_MPU_TO_HOST)
-		return MARS_ERROR_STATE;
 
-	mars_mutex_lock(queue_ea);
+	/* prepare work area */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_TASK_QUEUE_ALIGN, MARS_TASK_QUEUE_SIZE);
+
+	mars_mutex_lock_get(queue_ea, (struct mars_mutex *)queue);
+
+	ret = MARS_ERROR_STATE;
+	if (queue->direction != MARS_TASK_QUEUE_MPU_TO_HOST)
+		goto end;
 
 	/* queue is empty so wait */
 	while (!queue->count) {
-		mars_mutex_unlock(queue_ea);
+		mars_mutex_unlock_put(queue_ea, (struct mars_mutex *)queue);
 
 		/* only try so return busy */
 		if (try)
 			return MARS_ERROR_BUSY;
 
-		while (!queue->count)
+		while (!mars_ea_get_uint32(queue_count_ea(queue_ea)))
 			sched_yield();
 
-		mars_mutex_lock(queue_ea);
+		mars_mutex_lock_get(queue_ea, (struct mars_mutex *)queue);
 	}
 
 	/* copy data from queue */
-	memcpy(data, mars_ea_to_ptr(queue->pop_ea), queue->size);
+	mars_ea_get(queue->pop_ea, data, queue->size);
 
 	/* update queue data only if this is not a peek operation */
 	if (!peek)
 		pop_update(queue);
 
-	mars_mutex_unlock(queue_ea);
+	ret = MARS_SUCCESS;
+end:
+	mars_mutex_unlock_put(queue_ea, (struct mars_mutex *)queue);
 
-	return MARS_SUCCESS;
+	return ret;
 }
 
 int mars_task_queue_pop(uint64_t queue_ea, void *data)
--- a/modules/task/src/host/lib/task_semaphore.c
+++ b/modules/task/src/host/lib/task_semaphore.c
@@ -61,20 +61,26 @@ int mars_task_semaphore_create(struct ma
 		return MARS_ERROR_NULL;
 
 	/* allocate semaphore instance */
-	semaphore = (struct mars_task_semaphore *)mars_ea_memalign(
+	semaphore_ea = mars_ea_memalign(
 		MARS_TASK_SEMAPHORE_ALIGN, MARS_TASK_SEMAPHORE_SIZE);
-	if (!semaphore)
+	if (!semaphore_ea)
 		return MARS_ERROR_MEMORY;
 
-	semaphore_ea = mars_ptr_to_ea(semaphore);
-
-	mars_mutex_reset(semaphore_ea);
+	/* prepare work area for initialization */
+	semaphore = mars_ea_work_area_get(semaphore_ea,
+		MARS_TASK_SEMAPHORE_ALIGN, MARS_TASK_SEMAPHORE_SIZE);
 
 	/* initialize semaphore instance */
 	semaphore->mars_context_ea = mars_ptr_to_ea(mars);
 	semaphore->count = count;
 	semaphore->wait_count = 0;
 
+	/* update semaphore on EA */
+	mars_ea_put(semaphore_ea, semaphore, MARS_TASK_SEMAPHORE_SIZE);
+	mars_ea_sync();
+
+	mars_mutex_reset(semaphore_ea);
+
 	/* return semaphore instance */
 	*semaphore_ea_ret = semaphore_ea;
 
@@ -87,7 +93,7 @@ int mars_task_semaphore_destroy(uint64_t
 	if (!semaphore_ea)
 		return MARS_ERROR_NULL;
 
-	mars_ea_free(mars_ea_to_ptr(semaphore_ea));
+	mars_ea_free(semaphore_ea);
 
 	return MARS_SUCCESS;
 }






More information about the cbe-oss-dev mailing list