[Cbe-oss-dev] [PATCH 03/17]MARS/core: Wrap mpu management

Yuji Mano yuji.mano at am.sony.com
Wed Dec 3 13:58:45 EST 2008


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

Wrap MPU management functions

This patch wraps MPU management functions to prepare for hybrid system
support.

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
---
 core/src/host/configure.ac.in              |   17 ++++
 core/src/host/lib/Makefile.am              |    3 
 core/src/host/lib/context.c                |   73 ++++--------------
 core/src/host/lib/context_internal_types.h |   13 +++
 core/src/host/lib/mpu.c                    |  115 +++++++++++++++++++++++++++++
 5 files changed, 162 insertions(+), 59 deletions(-)

--- a/core/src/host/configure.ac.in
+++ b/core/src/host/configure.ac.in
@@ -40,6 +40,23 @@ AC_INIT([mars], [@version@], [MARS <cbe-
 
 AC_CONFIG_MARS_HOST
 
+# OS specific checks
+case "$host_os" in
+     cygwin* | mingw*)
+	;;
+     *)
+	AC_CHECK_HEADERS(pthread.h)
+	AC_CHECK_LIB(pthread, pthread_create)
+	;;
+esac
+
+# Platform specific checks
+case "$with_mars_platform" in
+     cell)
+	AC_CHECK_LIB(spe2, spe_context_create)
+	;;
+esac
+
 AC_CONFIG_AUX_DIR([.])
 
 AC_PROG_LIBTOOL
--- a/core/src/host/lib/Makefile.am
+++ b/core/src/host/lib/Makefile.am
@@ -96,6 +96,7 @@ libmars_core_la_SOURCES = \
 	alloc.c \
 	context.c \
 	ea.c \
+	mpu.c \
 	mutex.c \
 	workload_queue.c
 
@@ -120,8 +121,6 @@ libmars_core_la_LDFLAGS = \
 	-version-info 1:0:0 \
 	-Wl,-Map -Wl,$@.map -Wl,--cref
 
-libmars_core_la_LIBADD = -lspe2
-
 BUILT_SOURCES = mars_kernel.c
 
 CLEANFILES = mars_kernel.c *.eo *.map
--- a/core/src/host/lib/context.c
+++ b/core/src/host/lib/context.c
@@ -37,7 +37,6 @@
 
 #include <string.h>
 #include <pthread.h>
-#include <libspe2.h>
 #include <ppu_intrinsics.h>
 
 #include "config.h"
@@ -50,7 +49,6 @@
 #include "context_internal_types.h"
 #include "kernel_internal_types.h"
 
-extern const unsigned char mars_kernel_entry[];
 static struct mars_context *mars_shared_context;
 static pthread_mutex_t mars_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -81,40 +79,6 @@ static void kernel_ticks_sync(uint64_t k
 	mars_ea_put_uint32(flag_ea, MARS_KERNEL_TICKS_FLAG_SYNC_END);
 }
 
-static void *mpu_context_thread(void *arg)
-{
-	int ret;
-	unsigned int entry = SPE_DEFAULT_ENTRY;
-	struct mars_kernel_params *params = (struct mars_kernel_params *)arg;
-	struct spe_context *spe;
-	spe_program_handle_t prog;
-
-	spe = spe_context_create(0, NULL);
-	if (!spe)
-		return (void *)MARS_ERROR_INTERNAL;
-
-	memset(&prog, 0, sizeof(prog));
-	prog.handle_size = sizeof(prog);
-	prog.elf_image = (void *)mars_kernel_entry;
-	ret = spe_program_load(spe, &prog);
-	if (ret) {
-		spe_context_destroy(spe);
-		return (void *)MARS_ERROR_INTERNAL;
-	}
-
-	ret = spe_context_run(spe, &entry, 0, params, NULL, NULL);
-	if (ret) {
-		spe_context_destroy(spe);
-		return (void *)MARS_ERROR_INTERNAL;
-	}
-
-	ret = spe_context_destroy(spe);
-	if (ret)
-		return (void *)MARS_ERROR_INTERNAL;
-
-	return (void *)MARS_SUCCESS;
-}
-
 static int mpu_single_context_create(struct mars_context *mars, int index)
 {
 	int ret;
@@ -136,11 +100,9 @@ static int mpu_single_context_create(str
 	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;
+	ret = mars_mpu_run(&mars->mpu_contexts[index], params_ea);
+	if (ret != MARS_SUCCESS)
+		return ret;
 
 	kernel_ticks_sync(params_ea +
 			  offsetof(struct mars_kernel_params, kernel_ticks));
@@ -156,7 +118,7 @@ static int mpu_contexts_create(struct ma
 	/* create threads for each mpu context */
 	for (i = mars->mpu_context_count; i < num_mpus; i++) {
 		ret = mpu_single_context_create(mars, i);
-		if (ret)
+		if (ret != MARS_SUCCESS)
 			return ret;
 		mars->mpu_context_count++;
 	}
@@ -167,7 +129,6 @@ static int mpu_contexts_create(struct ma
 static int mpu_contexts_destroy(struct mars_context *mars)
 {
 	int ret;
-	void *p_ret;
 	unsigned int i;
 
 	/* shutdown the workload queue so mpu context threads exit */
@@ -177,9 +138,9 @@ static int mpu_contexts_destroy(struct m
 
 	/* join all mpu context threads */
 	for (i = 0; i < mars->mpu_context_count; i++) {
-		ret = pthread_join(mars->mpu_context_threads[i], &p_ret);
-		if (ret || p_ret)
-			return MARS_ERROR_INTERNAL;
+		ret = mars_mpu_wait(&mars->mpu_contexts[i]);
+		if (ret != MARS_SUCCESS)
+			return ret;
 	}
 
 	return MARS_SUCCESS;
@@ -197,9 +158,9 @@ int mars_context_create(struct mars_cont
 		return MARS_ERROR_NULL;
 
 	/* check number of mpus to use */
-	num_mpus_max = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
-	if (num_mpus_max <= 0)
-		return MARS_ERROR_INTERNAL;
+	ret = mars_mpu_max(&num_mpus_max);
+	if (ret != MARS_SUCCESS)
+		return ret;
 	if (num_mpus_max < (int)num_mpus)
 		return MARS_ERROR_PARAMS;
 	if (!num_mpus)
@@ -249,11 +210,11 @@ int mars_context_create(struct mars_cont
 	}
 
 	/* allocate mpu context thread array */
-	mars->mpu_context_threads = (pthread_t *)
-		mars_malloc(sizeof(pthread_t) * num_mpus_max);
-	if (!mars->mpu_context_threads) {
+	mars->mpu_contexts = (mars_mpu_context_t *)
+		mars_malloc(sizeof(mars_mpu_context_t) * num_mpus_max);
+	if (!mars->mpu_contexts) {
 		ret = MARS_ERROR_MEMORY;
-		goto error_malloc_mpu_context_threads;
+		goto error_malloc_mpu_contexts;
 	}
 
 	/* create workload queue */
@@ -288,8 +249,8 @@ error_pthread_mutex_unlock:
 error_mpu_contexts_create:
 	mars_workload_queue_destroy(mars);
 error_workload_queue_create:
-	mars_free(mars->mpu_context_threads);
-error_malloc_mpu_context_threads:
+	mars_free(mars->mpu_contexts);
+error_malloc_mpu_contexts:
 	mars_ea_free(mars->kernel_params_ea);
 error_malloc_kernel_params:
 	mars_free(mars);
@@ -334,7 +295,7 @@ int mars_context_destroy(struct mars_con
 	}
 
 	/* free allocated memory */
-	mars_free(mars->mpu_context_threads);
+	mars_free(mars->mpu_contexts);
 	mars_ea_free(mars->kernel_params_ea);
 	mars_free(mars);
 
--- a/core/src/host/lib/context_internal_types.h
+++ b/core/src/host/lib/context_internal_types.h
@@ -39,7 +39,14 @@
 #define MARS_CONTEXT_INTERNAL_TYPES_H
 
 #include <stdint.h>
+
+#ifdef HAVE_PTHREAD_H
 #include <pthread.h>
+#endif
+
+#ifdef HAVE_LIBSPE2
+typedef pthread_t mars_mpu_context_t;
+#endif
 
 struct mars_context {
 	/* parameters for the MARS kernel */
@@ -47,11 +54,15 @@ struct mars_context {
 	/* process queue where process requests are added */
 	uint64_t workload_queue_ea;
 	/* array of mpu context threads */
-	pthread_t *mpu_context_threads;
+	mars_mpu_context_t *mpu_contexts;
 	/* num of mpu context threads */
 	uint32_t mpu_context_count;
 	/* reference count */
 	uint32_t reference_count;
 };
 
+int mars_mpu_max(int *num);
+int mars_mpu_run(mars_mpu_context_t *mpu, uint64_t params_ea);
+int mars_mpu_wait(mars_mpu_context_t *mpu);
+
 #endif
--- /dev/null
+++ b/core/src/host/lib/mpu.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <string.h>
+#include <libspe2.h>
+
+#include "config.h"
+
+#include "mars/context.h"
+#include "mars/error.h"
+
+#include "context_internal_types.h"
+
+extern const unsigned char mars_kernel_entry[];
+
+int mars_mpu_max(int *num)
+{
+	*num = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
+	if (*num <= 0)
+		return MARS_ERROR_INTERNAL;
+
+	return MARS_SUCCESS;
+}
+
+static void *mpu_context_thread(void *arg)
+{
+	int ret;
+	unsigned int entry = SPE_DEFAULT_ENTRY;
+	struct mars_kernel_params *params = (struct mars_kernel_params *)arg;
+	struct spe_context *spe;
+	spe_program_handle_t prog;
+
+	spe = spe_context_create(0, NULL);
+	if (!spe)
+		return (void *)MARS_ERROR_INTERNAL;
+
+	memset(&prog, 0, sizeof(prog));
+	prog.handle_size = sizeof(prog);
+	prog.elf_image = (void *)mars_kernel_entry;
+	ret = spe_program_load(spe, &prog);
+	if (ret) {
+		spe_context_destroy(spe);
+		return (void *)MARS_ERROR_INTERNAL;
+	}
+
+	ret = spe_context_run(spe, &entry, 0, params, NULL, NULL);
+	if (ret) {
+		spe_context_destroy(spe);
+		return (void *)MARS_ERROR_INTERNAL;
+	}
+
+	ret = spe_context_destroy(spe);
+	if (ret)
+		return (void *)MARS_ERROR_INTERNAL;
+
+	return (void *)MARS_SUCCESS;
+}
+
+int mars_mpu_run(mars_mpu_context_t *mpu, uint64_t params_ea)
+{
+	int ret;
+
+	ret = pthread_create(mpu, NULL, mpu_context_thread,
+			     (void *)(uintptr_t)params_ea);
+	if (ret)
+		return MARS_ERROR_INTERNAL;
+
+	return MARS_SUCCESS;
+}
+
+int mars_mpu_wait(mars_mpu_context_t *mpu)
+{
+	int ret;
+	void *p_ret;
+
+	ret = pthread_join(*mpu, &p_ret);
+	if (ret || p_ret)
+		return MARS_ERROR_INTERNAL;
+
+	return MARS_SUCCESS;
+}






More information about the cbe-oss-dev mailing list