[Cbe-oss-dev] [PATCH 05/17]MARS/core: Separate ea from host

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


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

Separate EA space from host memory space (core)

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
---
 core/acinclude.m4                          |   26 +
 core/include/host/mars/core.h              |  137 +++++++++
 core/include/host/mars/mutex.h             |    7 
 core/src/common/workload_internal_types.h  |    4 
 core/src/host/lib/context.c                |   77 +++--
 core/src/host/lib/context_internal_types.h |    2 
 core/src/host/lib/ea.c                     |  102 +++++++
 core/src/host/lib/mutex.c                  |   43 ++-
 core/src/host/lib/workload_queue.c         |  398 ++++++++++++++++++-----------
 9 files changed, 612 insertions(+), 184 deletions(-)

--- a/core/acinclude.m4
+++ b/core/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/core/include/host/mars/core.h
+++ b/core/include/host/mars/core.h
@@ -46,6 +46,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <alloca.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -87,17 +88,145 @@ void mars_free(void *ptr);
  * \param[in] boundary		- memory address will be a multiple of boundary
  * \param[in] size		- size of memory block to allocate
  * \return
- *	void *			- pointer to allocated memory block
+ *	uint64_t		- 64-bit address of allocated memory block
  */
-void *mars_ea_memalign(size_t boundary, size_t size);
+uint64_t mars_ea_memalign(size_t boundary, size_t size);
 
 /**
  * \ingroup group_mars_core
  * \brief <b>[host]</b> Frees memory allocated in shared storage.
  *
- * \param[in] void *		- pointer to allocated memory block to free
+ * \param[in] ea		- 64-bit address of allocated memory block to free
+ */
+void mars_ea_free(uint64_t ea);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Allocates memory on the stack
+ *
+ * \param[in] boundary		- memory address will be a multiple of boundary
+ * \param[in] size		- size of memory block to allocate
+ * \return
+ *	void *			- pointer to allocated memory block
  */
-void mars_ea_free(void *ptr);
+#define mars_alloca_align(boundary, size)				\
+	( (void *)( ( (uintptr_t)alloca((size) + (boundary) - 1) +	\
+		      (boundary) - 1) &				\
+		    ~(uintptr_t)((boundary) - 1) ) )
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Copy memory block from host memory to shared memory.
+ *
+ * \param[in] ea		- 64-bit address of destination
+ * \param[in] ptr		- pointer to source
+ * \param[in] size		- size of memory block to copy
+ */
+void mars_ea_put(uint64_t ea, const void *ptr, size_t size);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Copy memory block from shared memory to host memory.
+ *
+ * \param[in] ea		- 64-bit address of source
+ * \param[in] ptr		- pointer to destination
+ * \param[in] size		- size of memory block to copy
+ */
+void mars_ea_get(uint64_t ea, void *ptr, size_t size);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Memory barrier
+ */
+void mars_ea_sync(void);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Get 16-bit integer value from shared memory
+ *
+ * \param[in] ea		- 64-bit address of source
+ *
+ * \return
+ *	uint16_t		- 16-bit result, no guarantee that it is loaded atomically
+ */
+uint16_t mars_ea_get_uint16(uint64_t ea);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Put 16-bit integer value to shared memory atomically
+ *
+ * \param[in] ea		- 64-bit address of destination
+ * \param[in] value		- 16-bit value to be stored in shared memory, no guarantee that it is stored atomically
+ */
+void mars_ea_put_uint16(uint64_t ea, uint16_t value);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Get 32-bit integer value from shared memory atomically
+ *
+ * \param[in] ea		- 64-bit address of source
+ *
+ * \return
+ *	uint32_t		- 32-bit result
+ */
+uint32_t mars_ea_get_uint32(uint64_t ea);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Put 32-bit integer value to shared memory atomically
+ *
+ * \param[in] ea		- 64-bit address of destination
+ * \param[in] value		- 32-bit value to be stored in shared memory
+ */
+void mars_ea_put_uint32(uint64_t ea, uint32_t value);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Get 64-bit integer value from shared memory
+ *
+ * \param[in] ea		- 64-bit address of source
+ *
+ * \return
+ *	uint64_t		- 64-bit result, no guarantee that it is loaded atomically
+ */
+uint64_t mars_ea_get_uint64(uint64_t ea);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Put 64-bit integer value to shared memory atomically
+ *
+ * \param[in] ea		- 64-bit address of destination
+ * \param[in] value		- 64-bit value to be stored in shared memory, no guarantee that it is stored atomically
+ */
+void mars_ea_put_uint64(uint64_t ea, uint64_t value);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Enable read access to data in specified memory block from MPU
+ *
+ * \param[in] ptr		- pointer to source
+ * \param[in] size		- size of memory block
+ *
+ * \return
+ *	uint64_t		- 64-bit address of memory block
+ */
+uint64_t mars_ea_map(void *ptr, size_t size);
+
+/**
+ * \ingroup group_mars_core
+ * \brief <b>[host]</b> Disable data access enabled by mars_ea_map
+ *
+ * \param[in] ea		- 64-bit address of memory block
+ * \param[in] size		- size of memory block
+ */
+void mars_ea_unmap(uint64_t ea, size_t size);
+
+#ifdef MARS_ENABLE_DISCRETE_SHARED_MEMORY
+#  define mars_ea_work_area_get(ea, boundary, size) mars_alloca_align(boundary, size)
+#else /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+	/* work area is unnecessary for non-discrete shared memory model */
+#  define mars_ea_work_area_get(ea, boundary, size) mars_ea_to_ptr(ea)
+#endif /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
 
 /**
  * \ingroup group_mars_core
--- a/core/include/host/mars/mutex.h
+++ b/core/include/host/mars/mutex.h
@@ -123,6 +123,13 @@ int mars_mutex_lock(uint64_t mutex_ea);
  */
 int mars_mutex_unlock(uint64_t mutex_ea);
 
+
+/* lock the mutex, then copy the mutex from EA to host */
+int mars_mutex_lock_get(uint64_t mutex_ea, struct mars_mutex *mutex);
+
+/* copy the mutex from host to EA, then unlock lock the mutex */
+int mars_mutex_unlock_put(uint64_t mutex_ea, struct mars_mutex *mutex);
+
 #if defined(__cplusplus)
 }
 #endif
--- a/core/src/common/workload_internal_types.h
+++ b/core/src/common/workload_internal_types.h
@@ -106,8 +106,8 @@
 struct mars_workload_queue_header {
 	uint64_t queue_ea;
 	uint64_t context_ea;
-	uint8_t flag;
-	uint8_t pad[MARS_WORKLOAD_QUEUE_HEADER_SIZE - 17];
+	uint32_t flag;
+	uint8_t pad[MARS_WORKLOAD_QUEUE_HEADER_SIZE - 20];
 } __attribute__((aligned(MARS_WORKLOAD_QUEUE_HEADER_ALIGN)));
 
 /* 128 byte workload queue block structure */
--- a/core/src/host/lib/context.c
+++ b/core/src/host/lib/context.c
@@ -59,20 +59,26 @@ uint32_t mars_get_ticks(void)
 	return __mftb() & 0xffffffff;
 }
 
-static void kernel_ticks_sync(volatile struct mars_kernel_ticks *kernel_ticks)
+static void kernel_ticks_sync(uint64_t kernel_ticks_ea)
 {
+	uint64_t flag_ea =
+		kernel_ticks_ea + offsetof(struct mars_kernel_ticks, flag);
+	uint64_t offset_ea =
+		kernel_ticks_ea + offsetof(struct mars_kernel_ticks, offset);
+
 	/* wait until kernel sets the sync begin flag */
 	do {
-	} while (kernel_ticks->flag != MARS_KERNEL_TICKS_FLAG_SYNC_BEGIN);
+	} while (mars_ea_get_uint32(flag_ea) !=
+		 MARS_KERNEL_TICKS_FLAG_SYNC_BEGIN);
 
-	__lwsync();
+	mars_ea_sync();
 
-	kernel_ticks->offset = mars_get_ticks();
+	mars_ea_put_uint32(offset_ea, mars_get_ticks());
 
-	__lwsync();
+	mars_ea_sync();
 
 	/* set the sync end flag so kernel can finish sync */
-	kernel_ticks->flag = MARS_KERNEL_TICKS_FLAG_SYNC_END;
+	mars_ea_put_uint32(flag_ea, MARS_KERNEL_TICKS_FLAG_SYNC_END);
 }
 
 static void *mpu_context_thread(void *arg)
@@ -105,6 +111,39 @@ static void *mpu_context_thread(void *ar
 	return (void *)MARS_SUCCESS;
 }
 
+static int mpu_single_context_create(struct mars_context *mars, int index)
+{
+	int ret;
+	uint64_t params_ea = mars->kernel_params_ea +
+		sizeof(struct mars_kernel_params) * index;
+	struct mars_kernel_params *params =
+		mars_ea_work_area_get(params_ea,
+				      MARS_KERNEL_PARAMS_ALIGN,
+				      sizeof(struct mars_kernel_params));
+
+	/* zero kernel params */
+	memset(params, 0, sizeof(struct mars_kernel_params));
+
+	params->kernel_id = index;
+	params->mars_context_ea = mars_ptr_to_ea(mars);
+	params->workload_queue_ea = mars->workload_queue_ea;
+
+	/* update params on EA */
+	mars_ea_put(params_ea, params, sizeof(struct mars_kernel_params));
+	mars_ea_sync();
+
+	ret = pthread_create(&mars->mpu_context_threads[index], NULL,
+			     mpu_context_thread,
+			     (void *)(uintptr_t)params_ea);
+	if (ret)
+		return MARS_ERROR_INTERNAL;
+
+	kernel_ticks_sync(params_ea +
+			  offsetof(struct mars_kernel_params, kernel_ticks));
+
+	return MARS_SUCCESS;
+}
+
 static int mpu_contexts_create(struct mars_context *mars, uint32_t num_mpus)
 {
 	int ret;
@@ -112,20 +151,9 @@ static int mpu_contexts_create(struct ma
 
 	/* create threads for each mpu context */
 	for (i = mars->mpu_context_count; i < num_mpus; i++) {
-		struct mars_kernel_params *params = &mars->kernel_params[i];
-
-		params->kernel_id = i;
-		params->mars_context_ea =
-			mars_ptr_to_ea(mars);
-		params->workload_queue_ea = mars->workload_queue_ea;
-
-		ret = pthread_create(&mars->mpu_context_threads[i], NULL,
-			mpu_context_thread, params);
+		ret = mpu_single_context_create(mars, i);
 		if (ret)
-			return MARS_ERROR_INTERNAL;
-
-		kernel_ticks_sync(&params->kernel_ticks);
-
+			return ret;
 		mars->mpu_context_count++;
 	}
 
@@ -208,16 +236,13 @@ int mars_context_create(struct mars_cont
 	mars->reference_count++;
 
 	/* allocate kernel params */
-	mars->kernel_params = (struct mars_kernel_params *)mars_ea_memalign(
+	mars->kernel_params_ea = mars_ea_memalign(
 			MARS_KERNEL_PARAMS_ALIGN,
 			sizeof(struct mars_kernel_params) * num_mpus_max);
-	if (!mars->kernel_params) {
+	if (!mars->kernel_params_ea) {
 		ret = MARS_ERROR_MEMORY;
 		goto error_malloc_kernel_params;
 	}
-	/* zero kernel params */
-	memset(mars->kernel_params, 0,
-		sizeof(struct mars_kernel_params) * num_mpus_max);
 
 	/* allocate mpu context thread array */
 	mars->mpu_context_threads = (pthread_t *)
@@ -261,7 +286,7 @@ error_mpu_contexts_create:
 error_workload_queue_create:
 	mars_free(mars->mpu_context_threads);
 error_malloc_mpu_context_threads:
-	mars_ea_free(mars->kernel_params);
+	mars_ea_free(mars->kernel_params_ea);
 error_malloc_kernel_params:
 	mars_free(mars);
 error:
@@ -306,7 +331,7 @@ int mars_context_destroy(struct mars_con
 
 	/* free allocated memory */
 	mars_free(mars->mpu_context_threads);
-	mars_ea_free(mars->kernel_params);
+	mars_ea_free(mars->kernel_params_ea);
 	mars_free(mars);
 
 	/* check if it is the shared context pointer and set to NULL */
--- a/core/src/host/lib/context_internal_types.h
+++ b/core/src/host/lib/context_internal_types.h
@@ -43,7 +43,7 @@
 
 struct mars_context {
 	/* parameters for the MARS kernel */
-	struct mars_kernel_params *kernel_params;
+	uint64_t kernel_params_ea;
 	/* process queue where process requests are added */
 	uint64_t workload_queue_ea;
 	/* array of mpu context threads */
--- a/core/src/host/lib/ea.c
+++ b/core/src/host/lib/ea.c
@@ -37,17 +37,111 @@
 
 #include <stdlib.h>
 #include <malloc.h>
+#include <string.h>
+#include <ppu_intrinsics.h>
 
 #include "config.h"
 
 #include "mars/core.h"
 
-void *mars_ea_memalign(size_t boundary, size_t size)
+uint64_t mars_ea_memalign(size_t boundary, size_t size)
 {
-	return memalign(boundary, size);
+	void *ptr = memalign(boundary, size);
+
+	return mars_ptr_to_ea(ptr);
+}
+
+void mars_ea_free(uint64_t ea)
+{
+	free(mars_ea_to_ptr(ea));
+}
+
+/* copy data from host to EA */
+void mars_ea_put(uint64_t ea, const void *mem, size_t size)
+{
+	void *dst = mars_ea_to_ptr(ea);
+	if (dst != mem)
+		memcpy(dst, mem, size);
+}
+
+/* copy data from EA to host */
+void mars_ea_get(uint64_t ea, void *mem, size_t size)
+{
+	const void *src = mars_ea_to_ptr(ea);
+	if (src != mem)
+		memcpy(mem, src, size);
+}
+
+/* map readonly area on host memory to EA */
+uint64_t mars_ea_map(void *ptr, size_t size)
+{
+#ifdef MARS_ENABLE_DISCRETE_SHARED_MEMORY
+	uint64_t copy_ea;
+
+	copy_ea = mars_ea_memalign(16, size); /* FIXME: 16 -> any macro */
+	if (!copy_ea)
+		return 0;
+
+	mars_ea_put(copy_ea, ptr, size);
+	mars_ea_sync();
+
+	return copy_ea;
+#else /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+	(void)size;
+	return mars_ptr_to_ea(ptr);
+#endif /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+}
+
+/* unmap area mapped by mars_ea_map */
+void mars_ea_unmap(uint64_t ea, size_t size)
+{
+	(void)size;
+
+#ifdef MARS_ENABLE_DISCRETE_SHARED_MEMORY
+	mars_ea_free(ea);
+#else /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+	(void)ea;
+#endif /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+}
+
+/* sync EA */
+void mars_ea_sync(void)
+{
+	__lwsync();
+}
+
+/* get uint16 value from EA */
+uint16_t mars_ea_get_uint16(uint64_t ea)
+{
+	return *(uint16_t *)mars_ea_to_ptr(ea);
+}
+
+/* put uint16 value to EA */
+void mars_ea_put_uint16(uint64_t ea, uint16_t value)
+{
+	*(uint16_t *)mars_ea_to_ptr(ea) = value;
+}
+
+/* get uint32 value from EA */
+uint32_t mars_ea_get_uint32(uint64_t ea)
+{
+	return *(uint32_t *)mars_ea_to_ptr(ea);
+}
+
+/* put uint32 value to EA */
+void mars_ea_put_uint32(uint64_t ea, uint32_t value)
+{
+	*(uint32_t *)mars_ea_to_ptr(ea) = value;
+}
+
+/* get uint64 value from EA */
+uint64_t mars_ea_get_uint64(uint64_t ea)
+{
+	return *(uint64_t *)mars_ea_to_ptr(ea);
 }
 
-void mars_ea_free(void *ptr)
+/* put uint64 value to EA */
+void mars_ea_put_uint64(uint64_t ea, uint64_t value)
 {
-	free(ptr);
+	*(uint64_t *)mars_ea_to_ptr(ea) = value;
 }
--- a/core/src/host/lib/mutex.c
+++ b/core/src/host/lib/mutex.c
@@ -46,19 +46,22 @@
 int mars_mutex_create(uint64_t *mutex_ea_ret)
 {
 	struct mars_mutex *mutex;
+	uint64_t mutex_ea;
 
 	if (!mutex_ea_ret)
 		return MARS_ERROR_NULL;
 
-	mutex = (struct mars_mutex *)mars_ea_memalign(
+	mutex_ea = mars_ea_memalign(
 		MARS_MUTEX_ALIGN, sizeof(struct mars_mutex));
-	if (!mutex)
+	if (!mutex_ea)
 		return MARS_ERROR_MEMORY;
 
+	mutex = mars_ea_to_ptr(mutex_ea);
+
 	mutex->lock = MARS_MUTEX_UNLOCKED;
 	__lwsync();
 
-	*mutex_ea_ret = mars_ptr_to_ea(mutex);
+	*mutex_ea_ret = mutex_ea;
 
 	return MARS_SUCCESS;
 }
@@ -68,7 +71,7 @@ int mars_mutex_destroy(uint64_t mutex_ea
 	if (!mutex_ea)
 		return MARS_ERROR_NULL;
 
-	mars_ea_free(mars_ea_to_ptr(mutex_ea));
+	mars_ea_free(mutex_ea);
 
 	return MARS_SUCCESS;
 }
@@ -118,3 +121,35 @@ int mars_mutex_unlock(uint64_t mutex_ea)
 
 	return MARS_SUCCESS;
 }
+
+int mars_mutex_lock_get(uint64_t mutex_ea, struct mars_mutex *mutex)
+{
+#ifdef MARS_ENABLE_DISCRETE_SHARED_MEMORY
+	int ret;
+	ret = mars_mutex_lock(mutex_ea);
+	if (ret != MARS_SUCCESS)
+		return ret;
+	mars_ea_get(mutex_ea, mutex, sizeof(struct mars_mutex));
+	return MARS_SUCCESS;
+#else /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+	(void)mutex; /* ignored */
+	return mars_mutex_lock(mutex_ea);
+#endif /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+}
+
+int mars_mutex_unlock_put(uint64_t mutex_ea, struct mars_mutex *mutex)
+{
+#ifdef MARS_ENABLE_DISCRETE_SHARED_MEMORY
+	int ret;
+	mars_ea_put(
+		mutex_ea + offsetof(struct mars_mutex, pad),
+		mutex->pad, sizeof(mutex->pad));
+	ret = mars_mutex_unlock(mutex_ea);
+	if (ret == MARS_SUCCESS)
+		mutex->lock = MARS_MUTEX_UNLOCKED;
+	return ret;
+#else /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+	(void)mutex; /* ignored */
+	return mars_mutex_unlock(mutex_ea);
+#endif /* !MARS_ENABLE_DISCRETE_SHARED_MEMORY */
+}
--- a/core/src/host/lib/workload_queue.c
+++ b/core/src/host/lib/workload_queue.c
@@ -57,12 +57,26 @@ static inline uint64_t workload_queue_bl
 		sizeof(struct mars_workload_queue_block) * block;
 }
 
-static inline uint64_t workload_queue_workload_ea(uint64_t context_ea, int workload_id)
+static inline uint64_t workload_queue_workload_ea(uint64_t queue_ea,
+						  int workload_id)
 {
+	uint64_t context_ea =
+		mars_ea_get_uint64(
+			queue_ea +
+			offsetof(struct mars_workload_queue_header,
+				 context_ea));
 	return context_ea +
 		sizeof(struct mars_workload_context) * workload_id;
 }
 
+static inline uint64_t workload_queue_block_bits_ea(uint64_t block_ea,
+						    int index)
+{
+	return block_ea +
+		offsetof(struct mars_workload_queue_block, bits) +
+		sizeof(uint64_t) * index;
+}
+
 int mars_workload_queue_create(struct mars_context *mars)
 {
 	struct mars_workload_queue *queue;
@@ -77,38 +91,55 @@ int mars_workload_queue_create(struct ma
 		return MARS_ERROR_STATE;
 
 	/* allocate workload instance */
-	queue = (struct mars_workload_queue *)mars_ea_memalign(
-		MARS_WORKLOAD_QUEUE_ALIGN, sizeof(struct mars_workload_queue));
-	if (!queue)
+	queue_ea = mars_ea_memalign(
+		MARS_WORKLOAD_QUEUE_ALIGN,
+		sizeof(struct mars_workload_queue));
+	if (!queue_ea)
 		return MARS_ERROR_MEMORY;
 
-	queue_ea = mars_ptr_to_ea(queue);
+	/* prepare work area for queue header */
+	queue = mars_ea_work_area_get(queue_ea,
+		MARS_WORKLOAD_QUEUE_ALIGN,
+		sizeof(struct mars_workload_queue_header));
 
 	/* initialize workload queue header */
 	queue->header.flag = MARS_WORKLOAD_QUEUE_FLAG_NONE;
 	queue->header.queue_ea = queue_ea;
-	queue->header.context_ea = mars_ptr_to_ea(&queue->context);
+	queue->header.context_ea =
+		queue_ea + offsetof(struct mars_workload_queue, context);
+
+	/* update queue header on EA */
+	mars_ea_put(queue_ea, queue, sizeof(struct mars_workload_queue_header));
 
 	/* initialize workload queue blocks */
 	for (block = 0; block < MARS_WORKLOAD_NUM_BLOCKS; block++) {
-		mars_mutex_reset(workload_queue_block_ea(queue_ea, block));
+		uint64_t block_ea = workload_queue_block_ea(queue_ea, block);
 
 		for (index = 0; index < MARS_WORKLOAD_PER_BLOCK; index++) {
-			uint64_t *bits = &queue->block[block].bits[index];
+			uint64_t bits_ea =
+				workload_queue_block_bits_ea(block_ea, index);
+			uint64_t bits = 0;
 
-			MARS_BITS_SET(bits, STATE,
+			MARS_BITS_SET(&bits, STATE,
 				MARS_WORKLOAD_STATE_NONE);
-			MARS_BITS_SET(bits, PRIORITY,
+			MARS_BITS_SET(&bits, PRIORITY,
 				MARS_WORKLOAD_PRIORITY_MIN);
-			MARS_BITS_SET(bits, COUNTER,
+			MARS_BITS_SET(&bits, COUNTER,
 				MARS_WORKLOAD_COUNTER_MIN);
-			MARS_BITS_SET(bits, SIGNAL,
+			MARS_BITS_SET(&bits, SIGNAL,
 				MARS_WORKLOAD_SIGNAL_OFF);
-			MARS_BITS_SET(bits, WAIT_ID,
+			MARS_BITS_SET(&bits, WAIT_ID,
 				MARS_WORKLOAD_ID_NONE);
+
+			mars_ea_put_uint64(bits_ea, bits);
 		}
+
+		mars_mutex_reset(block_ea);
 	}
 
+	/* sync EA */
+	mars_ea_sync();
+
 	/* set the workload queue instance in the mars context */
 	mars->workload_queue_ea = queue_ea;
 
@@ -117,7 +148,7 @@ int mars_workload_queue_create(struct ma
 
 int mars_workload_queue_destroy(struct mars_context *mars)
 {
-	struct mars_workload_queue *queue;
+	uint64_t queue_ea;
 	int block;
 	int index;
 	uint16_t id = 0;
@@ -128,22 +159,29 @@ int mars_workload_queue_destroy(struct m
 	if (!mars->workload_queue_ea)
 		return MARS_ERROR_STATE;
 
-	queue = mars_ea_to_ptr(mars->workload_queue_ea);
+	queue_ea = mars->workload_queue_ea;
 
 	/* check for any workloads left in workload queue */
 	while (id < MARS_WORKLOAD_MAX) {
+		uint64_t block_ea, bits_ea;
+		uint64_t bits;
+
 		block = id / MARS_WORKLOAD_PER_BLOCK;
 		index = id % MARS_WORKLOAD_PER_BLOCK;
 
-		if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-			MARS_WORKLOAD_STATE_NONE)
+		/* get bits from EA */
+		block_ea = workload_queue_block_ea(queue_ea, block);
+		bits_ea = workload_queue_block_bits_ea(block_ea, index);
+		bits = mars_ea_get_uint64(bits_ea);
+
+		if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_NONE)
 			return MARS_ERROR_STATE;
 
 		id++;
 	}
 
 	/* free workload queue instance */
-	mars_ea_free(queue);
+	mars_ea_free(queue_ea);
 
 	/* set the workload queue to NULL for error checking */
 	mars->workload_queue_ea = 0;
@@ -153,7 +191,7 @@ int mars_workload_queue_destroy(struct m
 
 int mars_workload_queue_exit(struct mars_context *mars)
 {
-	struct mars_workload_queue *queue;
+	uint64_t queue_ea;
 
 	/* check function params */
 	if (!mars)
@@ -161,9 +199,11 @@ int mars_workload_queue_exit(struct mars
 	if (!mars->workload_queue_ea)
 		return MARS_ERROR_STATE;
 
-	queue = mars_ea_to_ptr(mars->workload_queue_ea);
+	queue_ea = mars->workload_queue_ea;
 
-	queue->header.flag = MARS_WORKLOAD_QUEUE_FLAG_EXIT;
+	mars_ea_put_uint32(queue_ea +
+			   offsetof(struct mars_workload_queue_header, flag),
+			   MARS_WORKLOAD_QUEUE_FLAG_EXIT);
 
 	return MARS_SUCCESS;
 }
@@ -172,11 +212,11 @@ int mars_workload_queue_add_begin(struct
 				uint16_t *id,
 				uint64_t *workload_ea)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block = 0;
 	int index = 0;
-	uint64_t *bits;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -187,48 +227,53 @@ int mars_workload_queue_add_begin(struct
 		return MARS_ERROR_NULL;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
 
 	/* get bits from workload queue block */
-	bits = &queue->block[block].bits[index];
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* initialize return id to 0 */
 	*id = 0;
 
-	while (MARS_BITS_GET(bits, STATE) != MARS_WORKLOAD_STATE_NONE) {
+	while (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_NONE) {
 		(*id)++;
 		index++;
 		if (index == MARS_WORKLOAD_PER_BLOCK) {
 			index = 0;
 
-			mars_mutex_unlock(
-				workload_queue_block_ea(queue_ea, block));
+			mars_mutex_unlock(block_ea);
 
 			if (++block == MARS_WORKLOAD_NUM_BLOCKS)
 				return MARS_ERROR_LIMIT;
 
-			mars_mutex_lock(
-				workload_queue_block_ea(queue_ea, block));
+			block_ea = workload_queue_block_ea(queue_ea, block);
+			mars_mutex_lock(block_ea);
 		}
-		bits = &queue->block[block].bits[index];
+		bits_ea = workload_queue_block_bits_ea(block_ea, index);
+		bits = mars_ea_get_uint64(bits_ea);
 	}
 
 	/* check for valid state */
-	if (MARS_BITS_GET(bits, STATE) != MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_NONE) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state to adding */
-	MARS_BITS_SET(bits, STATE, MARS_WORKLOAD_STATE_ADDING);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_ADDING);
+
+	mars_ea_put_uint64(bits_ea, bits);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_mutex_unlock(block_ea);
 
 	/* if requested set workload context pointer to return */
 	if (workload_ea)
-		*workload_ea = workload_queue_workload_ea(queue->header.context_ea, *id);
+		*workload_ea = workload_queue_workload_ea(queue_ea, *id);
 
 	return MARS_SUCCESS;
 }
@@ -236,11 +281,11 @@ int mars_workload_queue_add_begin(struct
 int mars_workload_queue_add_end(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
-	uint64_t *bits;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -251,27 +296,32 @@ int mars_workload_queue_add_end(struct m
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
 
 	/* get bits from workload queue block */
-	bits = &queue->block[block].bits[index];
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(bits, STATE) != MARS_WORKLOAD_STATE_ADDING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_ADDING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* reset workload queue bits and set state to finished state */
-	MARS_BITS_SET(bits, STATE, MARS_WORKLOAD_STATE_FINISHED);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_FINISHED);
+
+	mars_ea_put_uint64(bits_ea, bits);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -279,10 +329,11 @@ int mars_workload_queue_add_end(struct m
 int mars_workload_queue_add_cancel(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -293,26 +344,32 @@ int mars_workload_queue_add_cancel(struc
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_ADDING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_ADDING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state back to none state */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_NONE);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_NONE);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_ea_put_uint64(bits_ea, bits);
+
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -321,10 +378,11 @@ int mars_workload_queue_remove_begin(str
 				uint16_t id,
 				uint64_t *workload_ea)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -335,30 +393,36 @@ int mars_workload_queue_remove_begin(str
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_FINISHED) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state to removing */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_REMOVING);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_REMOVING);
+
+	mars_ea_put_uint64(bits_ea, bits);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_mutex_unlock(block_ea);
 
 	/* if requested set workload context pointer to return */
 	if (workload_ea)
-		*workload_ea = workload_queue_workload_ea(queue->header.context_ea, id);
+		*workload_ea = workload_queue_workload_ea(queue_ea, id);
 
 	return MARS_SUCCESS;
 }
@@ -366,10 +430,11 @@ int mars_workload_queue_remove_begin(str
 int mars_workload_queue_remove_end(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -380,26 +445,32 @@ int mars_workload_queue_remove_end(struc
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_REMOVING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_REMOVING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state to none */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_NONE);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_NONE);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_ea_put_uint64(bits_ea, bits);
+
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -407,10 +478,11 @@ int mars_workload_queue_remove_end(struc
 int mars_workload_queue_remove_cancel(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -421,26 +493,32 @@ int mars_workload_queue_remove_cancel(st
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_REMOVING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_REMOVING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state back to finished */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_FINISHED);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_FINISHED);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_ea_put_uint64(bits_ea, bits);
+
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -449,10 +527,11 @@ int mars_workload_queue_schedule_begin(s
 				uint16_t id, uint8_t priority,
 				uint64_t *workload_ea)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -463,38 +542,40 @@ int mars_workload_queue_schedule_begin(s
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_FINISHED) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* reset workload queue bits and set state to scheduling */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_SCHEDULING);
-	MARS_BITS_SET(&queue->block[block].bits[index], PRIORITY,
-		priority);
-	MARS_BITS_SET(&queue->block[block].bits[index], COUNTER,
-		MARS_WORKLOAD_COUNTER_MIN);
-	MARS_BITS_SET(&queue->block[block].bits[index], SIGNAL,
-		MARS_WORKLOAD_SIGNAL_OFF);
-	MARS_BITS_SET(&queue->block[block].bits[index], WAIT_ID,
-		MARS_WORKLOAD_ID_NONE);
+	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);
+
+	mars_ea_put_uint64(bits_ea, bits);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_mutex_unlock(block_ea);
 
 	/* if requested set workload context pointer to return */
 	if (workload_ea)
-		*workload_ea = workload_queue_workload_ea(queue->header.context_ea, id);
+		*workload_ea = workload_queue_workload_ea(queue_ea, id);
 
 	return MARS_SUCCESS;
 }
@@ -502,10 +583,11 @@ int mars_workload_queue_schedule_begin(s
 int mars_workload_queue_schedule_end(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -516,26 +598,32 @@ int mars_workload_queue_schedule_end(str
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_SCHEDULING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_SCHEDULING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state to ready */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_READY);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_READY);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_ea_put_uint64(bits_ea, bits);
+
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -543,10 +631,11 @@ int mars_workload_queue_schedule_end(str
 int mars_workload_queue_schedule_cancel(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -557,26 +646,32 @@ int mars_workload_queue_schedule_cancel(
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_SCHEDULING) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_SCHEDULING) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set state back to finished */
-	MARS_BITS_SET(&queue->block[block].bits[index], STATE,
-		MARS_WORKLOAD_STATE_FINISHED);
+	MARS_BITS_SET(&bits, STATE, MARS_WORKLOAD_STATE_FINISHED);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_ea_put_uint64(bits_ea, bits);
+
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }
@@ -585,10 +680,11 @@ int mars_workload_queue_wait(struct mars
 				uint16_t id,
 				uint64_t *workload_ea)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -599,24 +695,28 @@ int mars_workload_queue_wait(struct mars
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	/* loop until workload state is finished */
-	while (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED) {
-		if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) ==
-			MARS_WORKLOAD_STATE_NONE)
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
+
+	while (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_FINISHED) {
+		if (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_NONE)
 			return MARS_ERROR_STATE;
 		sched_yield();
+		bits = mars_ea_get_uint64(bits_ea);
 	}
 
 	/* if requested set workload context pointer to return */
 	if (workload_ea)
-		*workload_ea = workload_queue_workload_ea(queue->header.context_ea, id);
+		*workload_ea = workload_queue_workload_ea(queue_ea, id);
 
 	return MARS_SUCCESS;
 }
@@ -625,10 +725,11 @@ int mars_workload_queue_try_wait(struct 
 				uint16_t id,
 				uint64_t *workload_ea)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -639,25 +740,29 @@ int mars_workload_queue_try_wait(struct 
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
+
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE)
+	if (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_NONE)
 		return MARS_ERROR_STATE;
 
 	/* check if workload is finished */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED)
+	if (MARS_BITS_GET(&bits, STATE) != MARS_WORKLOAD_STATE_FINISHED)
 		return MARS_ERROR_BUSY;
 
 	/* if requested set workload context pointer to return */
 	if (workload_ea)
-		*workload_ea = workload_queue_workload_ea(queue->header.context_ea, id);
+		*workload_ea = workload_queue_workload_ea(queue_ea, id);
 
 	return MARS_SUCCESS;
 }
@@ -665,10 +770,11 @@ int mars_workload_queue_try_wait(struct 
 int mars_workload_queue_signal_send(struct mars_context *mars,
 				uint16_t id)
 {
-	struct mars_workload_queue *queue;
 	uint64_t queue_ea;
 	int block;
 	int index;
+	uint64_t bits;
+	uint64_t block_ea, bits_ea;
 
 	/* check function params */
 	if (!mars)
@@ -679,26 +785,32 @@ int mars_workload_queue_signal_send(stru
 		return MARS_ERROR_PARAMS;
 
 	queue_ea = mars->workload_queue_ea;
-	queue = mars_ea_to_ptr(queue_ea);
 
 	/* calculate block/index from id */
 	block = id / MARS_WORKLOAD_PER_BLOCK;
 	index = id % MARS_WORKLOAD_PER_BLOCK;
 
-	mars_mutex_lock(workload_queue_block_ea(queue_ea, block));
+	/* prepare work area for queue block */
+	block_ea = workload_queue_block_ea(queue_ea, block);
+
+	mars_mutex_lock(block_ea);
+
+	/* get bits from workload queue block */
+	bits_ea = workload_queue_block_bits_ea(block_ea, index);
+	bits = mars_ea_get_uint64(bits_ea);
 
 	/* check for valid state */
-	if (MARS_BITS_GET(&queue->block[block].bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	if (MARS_BITS_GET(&bits, STATE) == MARS_WORKLOAD_STATE_NONE) {
+		mars_mutex_unlock(block_ea);
 		return MARS_ERROR_STATE;
 	}
 
 	/* set signal bit on */
-	MARS_BITS_SET(&queue->block[block].bits[index], SIGNAL,
-		MARS_WORKLOAD_SIGNAL_ON);
+	MARS_BITS_SET(&bits, SIGNAL, MARS_WORKLOAD_SIGNAL_ON);
+
+	mars_ea_put_uint64(bits_ea, bits);
 
-	mars_mutex_unlock(workload_queue_block_ea(queue_ea, block));
+	mars_mutex_unlock(block_ea);
 
 	return MARS_SUCCESS;
 }





More information about the cbe-oss-dev mailing list