[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