[Cbe-oss-dev] [PATCH 2/5]MARS/base: thread error handling fix

Yuji Mano yuji.mano at am.sony.com
Tue Jun 16 10:03:57 EST 2009


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 at am.sony.com>
---
 base/include/host/mars/context.h     |    2 
 base/src/host/lib/context.c          |    2 
 base/src/host/lib/context_internal.h |    7 +-
 base/src/host/lib/mpu_cell.c         |  120 ++++++++++++++---------------------
 4 files changed, 57 insertions(+), 74 deletions(-)

--- 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
--- 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);
--- 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
--- 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 *mp
 	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;
 }






More information about the cbe-oss-dev mailing list