Patchwork MARS: Add mars context header source

login
register
mail settings
Submitter Yuji Mano
Date Sept. 11, 2008, 7:34 p.m.
Message ID <48C972C9.9040106@am.sony.com>
Download mbox | patch
Permalink /patch/246/
State New
Delegated to: Yuji Mano
Headers show

Comments

Yuji Mano - Sept. 11, 2008, 7:34 p.m.
This adds a new header specifically for all MARS context types and API for the
host-side library, and removes them from the general "mars/mars.h" header.

Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>
Kazunori Asayama - Sept. 12, 2008, 7:12 a.m.
Yuji Mano wrote:
> This adds a new header specifically for all MARS context types and API for the
> host-side library, and removes them from the general "mars/mars.h" header.
> 
> Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>

Acked-by: Kazunori Asayama <asayama@sm.sony.co.jp>

> 
> ---
>  include/Makefile.am                 |    1 
>  include/host/mars/mars.h            |   85 --------------
>  include/host/mars/mars_context.h    |  132 ++++++++++++++++++++++
>  src/host/lib/Makefile.am            |    2 
>  src/host/lib/mars.c                 |  214 ------------------------------------
>  src/host/lib/mars_context.c         |  213 +++++++++++++++++++++++++++++++++++
>  src/host/lib/mars_task.c            |    2 
>  src/host/lib/mars_task_event_flag.c |    2 
>  src/host/lib/mars_task_queue.c      |    2 
>  src/host/lib/mars_task_signal.c     |    3 
>  10 files changed, 353 insertions(+), 303 deletions(-)
>

Patch

--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -50,6 +50,7 @@  host_HEADERS = \
 	common/mars/mars_task_queue_types.h \
 	common/mars/mars_task_semaphore_types.h \
 	host/mars/mars.h \
+	host/mars/mars_context.h \
 	host/mars/mars_mutex.h \
 	host/mars/mars_task.h \
 	host/mars/mars_task_barrier.h \
--- a/include/host/mars/mars.h
+++ b/include/host/mars/mars.h
@@ -44,92 +44,9 @@ 
  * \brief [host] MARS API
  */
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#include <pthread.h>
+#include "mars/mars_context.h"
 #include "mars/mars_error.h"
 #include "mars/mars_mutex.h"
 #include "mars/mars_task.h"
 
-/**
- * \ingroup group_mars_context
- * \brief MARS params structure
- *
- * This structure is initialized by the user and passed into
- * \ref mars_initialize for MARS context initialization.
- */
-struct mars_params {
-	/** number of mpus utilized by each MARS context
-	 * [between 0 and maximum available physical MPUs]
-	 */
-	unsigned int num_mpus;
-};
-
-/**
- * \ingroup group_mars_context
- * \brief MARS context structure
- *
- * An instance of this structure must be created and initialized before
- * using any of the MARS API.
- */
-struct mars_context {
-	/* parameters for the MARS context */
-	struct mars_params *params;
-	/* parameters for the MARS kernel */
-	struct mars_kernel_params *kernel_params;
-	/* process queue where process requests are added */
-	struct mars_workload_queue *workload_queue;
-	/* array of mpu context threads */
-	pthread_t *mpu_context_threads;
-	/* num of mpu context threads */
-	unsigned int mpu_context_count;
-};
-
-/**
- * \ingroup group_mars_context
- * \brief [host] Initializes a single MARS context.
- *
- * This function initializes a single MARS context. A MARS context must be
- * initialized before any of the MARS functionality can be used. This will
- * create the MPU contexts that are each loaded with and run the MARS kernel.
- * The MARS kernel on each MPU will continue to run until the MARS context
- * is finalized through \ref mars_finalize.
- *
- * \note If there are multiple MARS contexts initialized in the system, then
- * each MARS context will suffer the large over head of MPU context switches.
- *
- * \param[out] ctx		- address of context instance to initialize
- * \param[in] params		- pointer to MARS parameters structure
- * \return
- *	MARS_SUCCESS		- successfully initialized MARS context
- * \n	MARS_ERROR_NULL		- null pointer specified
- * \n	MARS_ERROR_PARAMS	- bad MARS params specified
- * \n	MARS_ERROR_MEMORY	- not enough memory
- * \n	MARS_ERROR_INTERNAL	- some internal error occurred
- */
-int mars_initialize(struct mars_context *ctx, struct mars_params *params);
-
-/**
- * \ingroup group_mars_context
- * \brief [host] Finalizes a single MARS context.
- *
- * This function finalizes a single MARS context that was previously
- * initialized by \ref mars_initialize. In order to successfully finalize
- * a MARS context, all workloads added to the workload queue must be
- * completed and finalized so that the workload queue is empty.
- *
- * \param[in] ctx		- address of context instance to finalize
- * \return
- *	MARS_SUCCESS		- successfully finalized MARS context
- * \n	MARS_ERROR_NULL		- null pointer specified
- * \n	MARS_ERROR_STATE	- workload queue is not empty
- */
-int mars_finalize(struct mars_context *ctx);
-
-#if defined(__cplusplus)
-}
-#endif
-
 #endif
--- /dev/null
+++ b/include/host/mars/mars_context.h
@@ -0,0 +1,132 @@ 
+/*
+ * Copyright 2008 Sony Corporation of America
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this Library and associated documentation files (the
+ * "Library"), to deal in the Library without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Library, and to
+ * permit persons to whom the Library is furnished to do so, subject to
+ * the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be
+ *  included in all copies or substantial portions of the Library.
+ *
+ *  If you modify the Library, you may copy and distribute your modified
+ *  version of the Library in object code or as an executable provided
+ *  that you also do one of the following:
+ *
+ *   Accompany the modified version of the Library with the complete
+ *   corresponding machine-readable source code for the modified version
+ *   of the Library; or,
+ *
+ *   Accompany the modified version of the Library with a written offer
+ *   for a complete machine-readable copy of the corresponding source
+ *   code of the modified version of the Library.
+ *
+ *
+ * THE LIBRARY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
+ */
+
+#ifndef MARS_CONTEXT_H
+#define MARS_CONTEXT_H
+
+/**
+ * \file
+ * \ingroup group_mars_context
+ * \brief [host] MARS Context API
+ */
+
+#include <pthread.h>
+
+/**
+ * \ingroup group_mars_context
+ * \brief MARS params structure
+ *
+ * This structure is initialized by the user and passed into
+ * \ref mars_initialize for MARS context initialization.
+ */
+struct mars_params {
+	/** number of mpus utilized by each MARS context
+	 * [between 0 and maximum available physical MPUs]
+	 */
+	unsigned int num_mpus;
+};
+
+/**
+ * \ingroup group_mars_context
+ * \brief MARS context structure
+ *
+ * An instance of this structure must be created and initialized before
+ * using any of the MARS API.
+ */
+struct mars_context {
+	/* parameters for the MARS context */
+	struct mars_params *params;
+	/* parameters for the MARS kernel */
+	struct mars_kernel_params *kernel_params;
+	/* process queue where process requests are added */
+	struct mars_workload_queue *workload_queue;
+	/* array of mpu context threads */
+	pthread_t *mpu_context_threads;
+	/* num of mpu context threads */
+	unsigned int mpu_context_count;
+};
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * \ingroup group_mars_context
+ * \brief [host] Initializes a single MARS context.
+ *
+ * This function initializes a single MARS context. A MARS context must be
+ * initialized before any of the MARS functionality can be used. This will
+ * create the MPU contexts that are each loaded with and run the MARS kernel.
+ * The MARS kernel on each MPU will continue to run until the MARS context
+ * is finalized through \ref mars_finalize.
+ *
+ * \note If there are multiple MARS contexts initialized in the system, then
+ * each MARS context will suffer the large over head of MPU context switches.
+ *
+ * \param[out] ctx		- address of context instance to initialize
+ * \param[in] params		- pointer to MARS parameters structure
+ * \return
+ *	MARS_SUCCESS		- successfully initialized MARS context
+ * \n	MARS_ERROR_NULL		- null pointer specified
+ * \n	MARS_ERROR_PARAMS	- bad MARS params specified
+ * \n	MARS_ERROR_MEMORY	- not enough memory
+ * \n	MARS_ERROR_INTERNAL	- some internal error occurred
+ */
+int mars_initialize(struct mars_context *ctx, struct mars_params *params);
+
+/**
+ * \ingroup group_mars_context
+ * \brief [host] Finalizes a single MARS context.
+ *
+ * This function finalizes a single MARS context that was previously
+ * initialized by \ref mars_initialize. In order to successfully finalize
+ * a MARS context, all workloads added to the workload queue must be
+ * completed and finalized so that the workload queue is empty.
+ *
+ * \param[in] ctx		- address of context instance to finalize
+ * \return
+ *	MARS_SUCCESS		- successfully finalized MARS context
+ * \n	MARS_ERROR_NULL		- null pointer specified
+ * \n	MARS_ERROR_STATE	- workload queue is not empty
+ */
+int mars_finalize(struct mars_context *ctx);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
--- a/src/host/lib/Makefile.am
+++ b/src/host/lib/Makefile.am
@@ -69,7 +69,7 @@  libmars_la_LDFLAGS = \
 	-Wl,../../mpu/kernel/mars_kernel.eo
 
 libmars_la_SOURCES = \
-	mars.c \
+	mars_context.c \
 	mars_mutex.c \
 	mars_workload_queue.c \
 	mars_task.c \
--- a/src/host/lib/mars.c
+++ /dev/null
@@ -1,214 +0,0 @@ 
-/*
- * Copyright 2008 Sony Corporation of America
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this Library and associated documentation files (the
- * "Library"), to deal in the Library without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Library, and to
- * permit persons to whom the Library is furnished to do so, subject to
- * the following conditions:
- *
- *  The above copyright notice and this permission notice shall be
- *  included in all copies or substantial portions of the Library.
- *
- *  If you modify the Library, you may copy and distribute your modified
- *  version of the Library in object code or as an executable provided
- *  that you also do one of the following:
- *
- *   Accompany the modified version of the Library with the complete
- *   corresponding machine-readable source code for the modified version
- *   of the Library; or,
- *
- *   Accompany the modified version of the Library with a written offer
- *   for a complete machine-readable copy of the corresponding source
- *   code of the modified version of the Library.
- *
- *
- * THE LIBRARY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
- */
-
-#include <malloc.h>
-#include <string.h>
-#include <pthread.h>
-#include <libspe2.h>
-
-#include "mars/mars.h"
-#include "mars/mars_workload_queue.h"
-#include "mars/mars_kernel_types.h"
-#include "mars/mars_error.h"
-#include "mars/mars_debug.h"
-
-extern struct spe_program_handle mars_kernel_entry;
-
-static unsigned int num_mpus_max(void)
-{
-	return spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
-}
-
-static void *mpu_context_thread(void *arg)
-{
-	MARS_ASSERT(arg);
-
-	int ret;
-	unsigned int entry = SPE_DEFAULT_ENTRY;
-	struct mars_kernel_params *params = (struct mars_kernel_params *)arg;
-	struct spe_context *spe;
-
-	spe = spe_context_create(0, NULL);
-	MARS_CHECK_RET(spe, (void *)MARS_ERROR_INTERNAL);
-
-	ret = spe_program_load(spe, &mars_kernel_entry);
-	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
-
-	ret = spe_context_run(spe, &entry, 0, params, NULL, NULL);
-	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
-
-	ret = spe_context_destroy(spe);
-	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
-
-	return (void *)MARS_SUCCESS;
-}
-
-static int create_mpu_contexts(struct mars_context *mars,
-				unsigned int num_mpu_contexts)
-{
-	MARS_ASSERT(mars);
-
-	int ret;
-	unsigned int i;
-
-	/* create threads for each mpu context */
-	for (i = 0; i < num_mpu_contexts; i++) {
-		struct mars_kernel_params *params = &mars->kernel_params[i];
-		params->id = i;
-		params->mars_context_ea =
-				(uint64_t)(uintptr_t)mars;
-		params->workload_queue_ea =
-				(uint64_t)(uintptr_t)mars->workload_queue;
-
-		ret = pthread_create(&mars->mpu_context_threads[i], NULL,
-				mpu_context_thread, params);
-		MARS_CHECK_RET(!ret, MARS_ERROR_INTERNAL);
-
-		mars->mpu_context_count++;
-	}
-
-	return MARS_SUCCESS;
-}
-
-static int destroy_mpu_contexts(struct mars_context *mars)
-{
-	MARS_ASSERT(mars);
-
-	int ret;
-	void *p_ret;
-	unsigned int i;
-
-	/* join all mpu context threads */
-	for (i = 0; i < mars->mpu_context_count; i++) {
-		ret = pthread_join(mars->mpu_context_threads[i], &p_ret);
-		MARS_CHECK_RET(!ret && !p_ret, MARS_ERROR_INTERNAL);
-	}
-
-	return MARS_SUCCESS;
-}
-
-int mars_initialize(struct mars_context *mars, struct mars_params *params)
-{
-	MARS_CHECK_RET(mars, MARS_ERROR_NULL);
-
-	MARS_PRINT("Initialize MARS Context (%p)\n", mars);
-
-	int ret;
-	unsigned int num_mpu_contexts;
-
-	/* zero context */
-	memset(mars, 0, sizeof(struct mars_context));
-
-	/* allocate and initialize params */
-	if (params) {
-		MARS_CHECK_RET(params->num_mpus <= num_mpus_max(),
-				MARS_ERROR_PARAMS);
-
-		mars->params = (struct mars_params *)
-			malloc(sizeof(struct mars_params));
-		MARS_CHECK_RET(mars->params, MARS_ERROR_MEMORY);
-		memcpy(mars->params, params, sizeof(struct mars_params));
-
-		num_mpu_contexts = mars->params->num_mpus;
-	} else {
-		mars->params = NULL;
-
-		num_mpu_contexts = num_mpus_max();
-	}
-
-	/* allocate kernel params */
-	mars->kernel_params = (struct mars_kernel_params *)
-		memalign(MARS_KERNEL_PARAMS_ALIGN,
-			sizeof(struct mars_kernel_params) * num_mpu_contexts);
-	MARS_CHECK_CLEANUP_RET(mars->kernel_params, mars_finalize(mars),
-				MARS_ERROR_MEMORY);
-
-	/* allocate workload queue */
-	mars->workload_queue = (struct mars_workload_queue *)
-		memalign(MARS_WORKLOAD_QUEUE_ALIGN,
-			sizeof(struct mars_workload_queue));
-	MARS_CHECK_CLEANUP_RET(mars->workload_queue, mars_finalize(mars),
-				MARS_ERROR_MEMORY);
-
-	/* initialize workload queue */
-	ret = workload_queue_initialize(mars->workload_queue);
-	MARS_CHECK_CLEANUP_RET(ret == MARS_SUCCESS, mars_finalize(mars), ret);
-
-	/* allocate mpu context thread array */
-	mars->mpu_context_threads = (pthread_t *)
-		malloc(sizeof(pthread_t) * num_mpu_contexts);
-	MARS_CHECK_CLEANUP_RET(mars->mpu_context_threads, mars_finalize(mars),
-				MARS_ERROR_MEMORY);
-
-	/* create contexts */
-	ret = create_mpu_contexts(mars, num_mpu_contexts);
-	MARS_CHECK_CLEANUP_RET(ret == MARS_SUCCESS, mars_finalize(mars), ret);
-
-	return MARS_SUCCESS;
-}
-
-int mars_finalize(struct mars_context *mars)
-{
-	MARS_CHECK_RET(mars, MARS_ERROR_NULL);
-
-	int ret;
-
-	/* finalize workload queue */
-	if (mars->workload_queue) {
-		ret = workload_queue_finalize(mars->workload_queue);
-		MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
-	}
-
-	/* destroy contexts */
-	if (mars->mpu_context_count) {
-		ret = destroy_mpu_contexts(mars);
-		MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
-	}
-
-	/* free allocated memory */
-	free(mars->params);
-	free(mars->kernel_params);
-	free(mars->workload_queue);
-	free(mars->mpu_context_threads);
-
-	/* zero context */
-	memset(mars, 0, sizeof(struct mars_context));
-
-	MARS_PRINT("Finalize MARS Context (%p)\n", mars);
-
-	return MARS_SUCCESS;
-}
--- /dev/null
+++ b/src/host/lib/mars_context.c
@@ -0,0 +1,213 @@ 
+/*
+ * Copyright 2008 Sony Corporation of America
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this Library and associated documentation files (the
+ * "Library"), to deal in the Library without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Library, and to
+ * permit persons to whom the Library is furnished to do so, subject to
+ * the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be
+ *  included in all copies or substantial portions of the Library.
+ *
+ *  If you modify the Library, you may copy and distribute your modified
+ *  version of the Library in object code or as an executable provided
+ *  that you also do one of the following:
+ *
+ *   Accompany the modified version of the Library with the complete
+ *   corresponding machine-readable source code for the modified version
+ *   of the Library; or,
+ *
+ *   Accompany the modified version of the Library with a written offer
+ *   for a complete machine-readable copy of the corresponding source
+ *   code of the modified version of the Library.
+ *
+ *
+ * THE LIBRARY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
+ */
+
+#include <malloc.h>
+#include <string.h>
+#include <pthread.h>
+#include <libspe2.h>
+
+#include "mars/mars_context.h"
+#include "mars/mars_workload_queue.h"
+#include "mars/mars_kernel_types.h"
+#include "mars/mars_error.h"
+#include "mars/mars_debug.h"
+
+extern struct spe_program_handle mars_kernel_entry;
+
+static int num_mpus_max(void)
+{
+	return spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
+}
+
+static void *mpu_context_thread(void *arg)
+{
+	MARS_ASSERT(arg);
+
+	int ret;
+	unsigned int entry = SPE_DEFAULT_ENTRY;
+	struct mars_kernel_params *params = (struct mars_kernel_params *)arg;
+	struct spe_context *spe;
+
+	spe = spe_context_create(0, NULL);
+	MARS_CHECK_RET(spe, (void *)MARS_ERROR_INTERNAL);
+
+	ret = spe_program_load(spe, &mars_kernel_entry);
+	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
+
+	ret = spe_context_run(spe, &entry, 0, params, NULL, NULL);
+	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
+
+	ret = spe_context_destroy(spe);
+	MARS_CHECK_RET(!ret, (void *)MARS_ERROR_INTERNAL);
+
+	return (void *)MARS_SUCCESS;
+}
+
+static int create_mpu_contexts(struct mars_context *mars, int num_mpu_contexts)
+{
+	MARS_ASSERT(mars);
+
+	int ret;
+	unsigned int i;
+
+	/* create threads for each mpu context */
+	for (i = 0; i < num_mpu_contexts; i++) {
+		struct mars_kernel_params *params = &mars->kernel_params[i];
+		params->id = i;
+		params->mars_context_ea =
+				(uint64_t)(uintptr_t)mars;
+		params->workload_queue_ea =
+				(uint64_t)(uintptr_t)mars->workload_queue;
+
+		ret = pthread_create(&mars->mpu_context_threads[i], NULL,
+				mpu_context_thread, params);
+		MARS_CHECK_RET(!ret, MARS_ERROR_INTERNAL);
+
+		mars->mpu_context_count++;
+	}
+
+	return MARS_SUCCESS;
+}
+
+static int destroy_mpu_contexts(struct mars_context *mars)
+{
+	MARS_ASSERT(mars);
+
+	int ret;
+	void *p_ret;
+	unsigned int i;
+
+	/* join all mpu context threads */
+	for (i = 0; i < mars->mpu_context_count; i++) {
+		ret = pthread_join(mars->mpu_context_threads[i], &p_ret);
+		MARS_CHECK_RET(!ret && !p_ret, MARS_ERROR_INTERNAL);
+	}
+
+	return MARS_SUCCESS;
+}
+
+int mars_initialize(struct mars_context *mars, struct mars_params *params)
+{
+	MARS_CHECK_RET(mars, MARS_ERROR_NULL);
+
+	MARS_PRINT("Initialize MARS Context (%p)\n", mars);
+
+	int ret;
+	unsigned int num_mpu_contexts;
+
+	/* zero context */
+	memset(mars, 0, sizeof(struct mars_context));
+
+	/* allocate and initialize params */
+	if (params) {
+		MARS_CHECK_RET(params->num_mpus <= num_mpus_max(),
+				MARS_ERROR_PARAMS);
+
+		mars->params = (struct mars_params *)
+			malloc(sizeof(struct mars_params));
+		MARS_CHECK_RET(mars->params, MARS_ERROR_MEMORY);
+		memcpy(mars->params, params, sizeof(struct mars_params));
+
+		num_mpu_contexts = mars->params->num_mpus;
+	} else {
+		mars->params = NULL;
+
+		num_mpu_contexts = num_mpus_max();
+	}
+
+	/* allocate kernel params */
+	mars->kernel_params = (struct mars_kernel_params *)
+		memalign(MARS_KERNEL_PARAMS_ALIGN,
+			sizeof(struct mars_kernel_params) * num_mpu_contexts);
+	MARS_CHECK_CLEANUP_RET(mars->kernel_params, mars_finalize(mars),
+				MARS_ERROR_MEMORY);
+
+	/* allocate workload queue */
+	mars->workload_queue = (struct mars_workload_queue *)
+		memalign(MARS_WORKLOAD_QUEUE_ALIGN,
+			sizeof(struct mars_workload_queue));
+	MARS_CHECK_CLEANUP_RET(mars->workload_queue, mars_finalize(mars),
+				MARS_ERROR_MEMORY);
+
+	/* initialize workload queue */
+	ret = workload_queue_initialize(mars->workload_queue);
+	MARS_CHECK_CLEANUP_RET(ret == MARS_SUCCESS, mars_finalize(mars), ret);
+
+	/* allocate mpu context thread array */
+	mars->mpu_context_threads = (pthread_t *)
+		malloc(sizeof(pthread_t) * num_mpu_contexts);
+	MARS_CHECK_CLEANUP_RET(mars->mpu_context_threads, mars_finalize(mars),
+				MARS_ERROR_MEMORY);
+
+	/* create contexts */
+	ret = create_mpu_contexts(mars, num_mpu_contexts);
+	MARS_CHECK_CLEANUP_RET(ret == MARS_SUCCESS, mars_finalize(mars), ret);
+
+	return MARS_SUCCESS;
+}
+
+int mars_finalize(struct mars_context *mars)
+{
+	MARS_CHECK_RET(mars, MARS_ERROR_NULL);
+
+	int ret;
+
+	/* finalize workload queue */
+	if (mars->workload_queue) {
+		ret = workload_queue_finalize(mars->workload_queue);
+		MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
+	}
+
+	/* destroy contexts */
+	if (mars->mpu_context_count) {
+		ret = destroy_mpu_contexts(mars);
+		MARS_CHECK_RET(ret == MARS_SUCCESS, ret);
+	}
+
+	/* free allocated memory */
+	free(mars->params);
+	free(mars->kernel_params);
+	free(mars->workload_queue);
+	free(mars->mpu_context_threads);
+
+	/* zero context */
+	memset(mars, 0, sizeof(struct mars_context));
+
+	MARS_PRINT("Finalize MARS Context (%p)\n", mars);
+
+	return MARS_SUCCESS;
+}
--- a/src/host/lib/mars_task.c
+++ b/src/host/lib/mars_task.c
@@ -41,7 +41,7 @@ 
 
 #include "mars/mars_task.h"
 #include "mars/mars_workload_queue.h"
-#include "mars/mars.h"
+#include "mars/mars_context.h"
 #include "mars/mars_error.h"
 #include "mars/mars_debug.h"
 
--- a/src/host/lib/mars_task_event_flag.c
+++ b/src/host/lib/mars_task_event_flag.c
@@ -40,7 +40,7 @@ 
 
 #include "mars/mars_task_event_flag.h"
 #include "mars/mars_workload_queue.h"
-#include "mars/mars.h"
+#include "mars/mars_context.h"
 #include "mars/mars_mutex.h"
 #include "mars/mars_error.h"
 #include "mars/mars_debug.h"
--- a/src/host/lib/mars_task_queue.c
+++ b/src/host/lib/mars_task_queue.c
@@ -40,7 +40,7 @@ 
 
 #include "mars/mars_task_queue.h"
 #include "mars/mars_workload_queue.h"
-#include "mars/mars.h"
+#include "mars/mars_context.h"
 #include "mars/mars_mutex.h"
 #include "mars/mars_error.h"
 #include "mars/mars_debug.h"
--- a/src/host/lib/mars_task_signal.c
+++ b/src/host/lib/mars_task_signal.c
@@ -36,7 +36,8 @@ 
  */
 
 #include "mars/mars_task_signal.h"
-#include "mars/mars.h"
+#include "mars/mars_workload_queue.h"
+#include "mars/mars_context.h"
 #include "mars/mars_error.h"
 #include "mars/mars_debug.h"
 #include "mars/mars_workload_queue.h"