aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuji Mano <yuji.mano@am.sony.com>2009-06-15 17:03:57 -0700
committerYuji Mano <yuji.mano@am.sony.com>2009-07-07 12:24:36 -0700
commit83ab241b188f46c02842b640ad0131ff529e72f6 (patch)
tree81602a9ada067716544d76fc9372d90766c5498b
parentfab8eb53d9f74410946f8a08c342e65cc9d51641 (diff)
downloadmars-src-83ab241b188f46c02842b640ad0131ff529e72f6.tar.gz
base: thread error handling fix
This fixes some implementation logic for mpu context creation so that critical pthread errors are handled more appropriately. Signed-off-by: Yuji Mano <yuji.mano@am.sony.com> Acked-by: Kazunori Asayama <asayama@sm.sony.co.jp>
-rw-r--r--base/include/host/mars/context.h2
-rw-r--r--base/src/host/lib/context.c2
-rw-r--r--base/src/host/lib/context_internal.h7
-rw-r--r--base/src/host/lib/mpu_cell.c120
4 files changed, 57 insertions, 74 deletions
diff --git a/base/include/host/mars/context.h b/base/include/host/mars/context.h
index 1a6de69..a5053d1 100644
--- a/base/include/host/mars/context.h
+++ b/base/include/host/mars/context.h
@@ -93,7 +93,7 @@ extern "C" {
* \return
* MARS_SUCCESS - successfully created MARS context
* \n MARS_ERROR_NULL - null pointer specified
- * \n MARS_ERROR_LIMIT - no more available MPUs
+ * \n MARS_ERROR_LIMIT - no more available MPUs or system threads
* \n MARS_ERROR_PARAMS - more MPUs requested than there are available
* \n MARS_ERROR_MEMORY - not enough memory
* \n MARS_ERROR_INTERNAL - some internal error occurred
diff --git a/base/src/host/lib/context.c b/base/src/host/lib/context.c
index 6e29027..00a6069 100644
--- a/base/src/host/lib/context.c
+++ b/base/src/host/lib/context.c
@@ -293,8 +293,10 @@ done:
error_shared_context_unlock:
mpu_contexts_destroy(mars);
error_mpu_contexts_create:
+ mars_callback_queue_exit(mars);
mars_callback_queue_destroy(mars);
error_callback_queue_create:
+ mars_workload_queue_exit(mars);
mars_workload_queue_destroy(mars);
error_workload_queue_create:
mars_free(mars->mpu_contexts);
diff --git a/base/src/host/lib/context_internal.h b/base/src/host/lib/context_internal.h
index ef8e0e3..079ebd6 100644
--- a/base/src/host/lib/context_internal.h
+++ b/base/src/host/lib/context_internal.h
@@ -47,7 +47,12 @@
#define MARS_SHARED_CONTEXT_MAX 16
#ifdef HAVE_LIBSPE2
-typedef pthread_t mars_mpu_context_t;
+#include <libspe2.h>
+typedef struct {
+ pthread_t mpu_context_thread;
+ pthread_t mpu_handler_thread;
+ spe_context_ptr_t spe_context;
+} mars_mpu_context_t;
#endif
#ifdef HAVE_LIBPTHREAD
diff --git a/base/src/host/lib/mpu_cell.c b/base/src/host/lib/mpu_cell.c
index 49744fd..594e754 100644
--- a/base/src/host/lib/mpu_cell.c
+++ b/base/src/host/lib/mpu_cell.c
@@ -36,7 +36,6 @@
*/
#include <string.h>
-#include <libspe2.h>
#include "config.h"
@@ -143,97 +142,66 @@ error:
return (void *)(uintptr_t)MARS_ERROR_INTERNAL;
}
-static int handler_thread_create(pthread_t *thread, spe_context_ptr_t spe)
-{
- int ret;
-
- ret = pthread_create(thread, NULL, mpu_handler_thread, spe);
- if (ret)
- return MARS_ERROR_INTERNAL;
-
- return MARS_SUCCESS;
-}
-
-static int handler_thread_join(pthread_t thread)
-{
- int ret;
-
- ret = pthread_join(thread, NULL);
- if (ret)
- return MARS_ERROR_INTERNAL;
-
- return MARS_SUCCESS;
-}
-
-#else /* !ENABLE_COND_WAIT_FUTEX */
-
-static int handler_thread_create(pthread_t *thread, spe_context_ptr_t spe)
-{
- (void)thread;
-
- return MARS_SUCCESS;
-}
-
-static int handler_thread_join(pthread_t thread)
-{
- (void)thread;
-
- return MARS_SUCCESS;
-}
+#endif /* ENABLE_COND_WAIT_FUTEX */
-#endif /* !ENABLE_COND_WAIT_FUTEX */
+struct mars_mpu_context_thread_arg {
+ spe_context_ptr_t spe_context;
+ uint64_t params_ea;
+};
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;
- spe_context_ptr_t spe;
spe_program_handle_t prog;
- pthread_t handler_thread;
-
- spe = spe_context_create(0, NULL);
- if (!spe)
- return (void *)MARS_ERROR_INTERNAL;
+ struct mars_mpu_context_thread_arg *thread_arg =
+ (struct mars_mpu_context_thread_arg *)arg;
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 = handler_thread_create(&handler_thread, spe);
- if (ret) {
- spe_context_destroy(spe);
- return (void *)ret;
- }
-
- ret = spe_context_run(spe, &entry, 0, params, NULL, NULL);
- if (ret) {
- spe_context_destroy(spe);
- return (void *)MARS_ERROR_INTERNAL;
- }
- handler_thread_join(handler_thread);
+ ret = spe_program_load(thread_arg->spe_context, &prog);
+ if (ret)
+ return (void *)(uintptr_t)MARS_ERROR_INTERNAL;
- ret = spe_context_destroy(spe);
+ ret = spe_context_run(thread_arg->spe_context, &entry, 0,
+ mars_ea_to_ptr(thread_arg->params_ea), NULL,
+ NULL);
if (ret)
- return (void *)MARS_ERROR_INTERNAL;
+ return (void *)(uintptr_t)MARS_ERROR_INTERNAL;
- return (void *)MARS_SUCCESS;
+ return (void *)(uintptr_t)MARS_SUCCESS;
}
int mars_mpu_run(mars_mpu_context_t *mpu, uint64_t params_ea)
{
int ret;
+ static struct mars_mpu_context_thread_arg thread_arg;
- ret = pthread_create(mpu, NULL, mpu_context_thread,
- (void *)(uintptr_t)params_ea);
- if (ret)
- return MARS_ERROR_INTERNAL;
+ mpu->spe_context = spe_context_create(0, NULL);
+ if (!mpu->spe_context)
+ return errno == ENOMEM ? MARS_ERROR_MEMORY :
+ MARS_ERROR_INTERNAL;
+
+#ifdef ENABLE_COND_WAIT_FUTEX
+ ret = pthread_create(&mpu->mpu_handler_thread, NULL,
+ mpu_handler_thread, mpu->spe_context);
+ if (ret) {
+ spe_context_destroy(mpu->spe_context);
+ return ret == EAGAIN ? MARS_ERROR_LIMIT : MARS_ERROR_INTERNAL;
+ }
+#endif /* ENABLE_COND_WAIT_FUTEX */
+
+ thread_arg.spe_context = mpu->spe_context;
+ thread_arg.params_ea = params_ea;
+
+ ret = pthread_create(&mpu->mpu_context_thread, NULL,
+ mpu_context_thread, &thread_arg);
+ if (ret) {
+ spe_context_destroy(mpu->spe_context);
+ return ret == EAGAIN ? MARS_ERROR_LIMIT : MARS_ERROR_INTERNAL;
+ }
return MARS_SUCCESS;
}
@@ -243,9 +211,17 @@ int mars_mpu_wait(mars_mpu_context_t *mpu)
int ret;
void *p_ret;
- ret = pthread_join(*mpu, &p_ret);
+ ret = pthread_join(mpu->mpu_context_thread, &p_ret);
if (ret || p_ret)
return MARS_ERROR_INTERNAL;
+ ret = pthread_join(mpu->mpu_handler_thread, &p_ret);
+ if (ret || p_ret)
+ return MARS_ERROR_INTERNAL;
+
+ ret = spe_context_destroy(mpu->spe_context);
+ if (ret)
+ return MARS_ERROR_INTERNAL;
+
return MARS_SUCCESS;
}