diff options
author | Yuji Mano <yuji.mano@am.sony.com> | 2009-06-15 17:03:57 -0700 |
---|---|---|
committer | Yuji Mano <yuji.mano@am.sony.com> | 2009-07-07 12:24:36 -0700 |
commit | 83ab241b188f46c02842b640ad0131ff529e72f6 (patch) | |
tree | 81602a9ada067716544d76fc9372d90766c5498b | |
parent | fab8eb53d9f74410946f8a08c342e65cc9d51641 (diff) | |
download | mars-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.h | 2 | ||||
-rw-r--r-- | base/src/host/lib/context.c | 2 | ||||
-rw-r--r-- | base/src/host/lib/context_internal.h | 7 | ||||
-rw-r--r-- | base/src/host/lib/mpu_cell.c | 120 |
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; } |