[rtems-libbsd commit] threads: Delay thread start during initialization

Sebastian Huber sebh at rtems.org
Wed Nov 13 16:38:35 UTC 2013


Module:    rtems-libbsd
Branch:    master
Commit:    c2f6513a058048cf45b98f1d4e265f1ff969e190
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=c2f6513a058048cf45b98f1d4e265f1ff969e190

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Nov 13 16:52:02 2013 +0100

threads: Delay thread start during initialization

The FreeBSD initialization is supposed to be single-threaded.

---

 rtemsbsd/rtems/rtems-bsd-thread.c |   65 +++++++++++++++++++++++++++++++------
 1 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/rtemsbsd/rtems/rtems-bsd-thread.c b/rtemsbsd/rtems/rtems-bsd-thread.c
index 8cb09d7..b2b71c2 100644
--- a/rtemsbsd/rtems/rtems-bsd-thread.c
+++ b/rtemsbsd/rtems/rtems-bsd-thread.c
@@ -61,35 +61,39 @@ RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_thread_chain);
 
 static size_t rtems_bsd_extension_index;
 
+static CHAIN_DEFINE_EMPTY(rtems_bsd_thread_delay_start_chain);
+
+static bool rtems_bsd_thread_ready_to_start;
+
 struct thread *
 rtems_bsd_get_thread(const Thread_Control *thread)
 {
 	return thread->extensions[rtems_bsd_extension_index];
 }
 
-static struct thread *
+static Thread_Control *
 rtems_bsd_get_thread_by_id(rtems_id task_id)
 {
-	struct thread *td = NULL;
 	Thread_Control *thread;
 	Objects_Locations location;
 
 	thread = _Thread_Get(task_id, &location);
 	switch (location) {
 		case OBJECTS_LOCAL:
-			td = rtems_bsd_get_thread(thread);
 			_Objects_Put(&thread->Object);
 			break;
 #if defined(RTEMS_MULTIPROCESSING)
 		case OBJECTS_REMOTE:
 			_Thread_Dispatch();
+			thread = NULL;
 			break;
 #endif
 		default:
+			thread = NULL;
 			break;
 	}
 
-	return td;
+	return thread;
 }
 
 struct thread *
@@ -198,11 +202,13 @@ static const rtems_extensions_table rtems_bsd_extensions = {
 };
 
 static void
-rtems_bsd_threads_init(void *arg __unused)
+rtems_bsd_threads_init_early(void *arg)
 {
 	rtems_id ext_id;
 	rtems_status_code sc;
 
+	(void) arg;
+
 	sc = rtems_extension_create(
 		BSD_TASK_NAME,
 		&rtems_bsd_extensions,
@@ -215,10 +221,35 @@ rtems_bsd_threads_init(void *arg __unused)
 	rtems_bsd_extension_index = rtems_object_id_get_index(ext_id);
 }
 
-SYSINIT(rtems_bsd_threads, SI_SUB_INTRINSIC, SI_ORDER_ANY, rtems_bsd_threads_init, NULL);
+static void
+rtems_bsd_threads_init_late(void *arg)
+{
+	Chain_Control *chain = &rtems_bsd_thread_delay_start_chain;
+	Chain_Node *node;
+
+	(void) arg;
+
+	while ((node = _Chain_Get_unprotected(chain)) != NULL) {
+		Thread_Control *thread = (Thread_Control *) node;
+		rtems_status_code sc;
+
+		sc = rtems_task_start(thread->Object.id, (rtems_task_entry)
+		    thread->Start.entry_point, thread->Start.numeric_argument);
+		BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+	}
+
+	rtems_bsd_thread_ready_to_start = true;
+}
+
+SYSINIT(rtems_bsd_threads_early, SI_SUB_INTRINSIC, SI_ORDER_ANY,
+    rtems_bsd_threads_init_early, NULL);
+
+SYSINIT(rtems_bsd_threads_late, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY,
+    rtems_bsd_threads_init_late, NULL);
 
 static int
-rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg, int flags, int pages, const char *fmt, va_list ap)
+rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg,
+    int flags, int pages, const char *fmt, va_list ap)
 {
 	int eno = 0;
 	rtems_status_code sc;
@@ -235,14 +266,28 @@ rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg,
 		&task_id
 	);
 	if (sc == RTEMS_SUCCESSFUL) {
-		struct thread *td = rtems_bsd_get_thread_by_id(task_id);
+		Thread_Control *thread = rtems_bsd_get_thread_by_id(task_id);
+		struct thread *td;
+
+		BSD_ASSERT(thread != NULL);
 
+		td = rtems_bsd_get_thread(thread);
 		BSD_ASSERT(td != NULL);
 
 		vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
 
-		sc = rtems_task_start(task_id, (rtems_task_entry) func, (rtems_task_argument) arg);
-		BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+		if (rtems_bsd_thread_ready_to_start) {
+			sc = rtems_task_start(task_id, (rtems_task_entry) func,
+			    (rtems_task_argument) arg);
+			BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+		} else {
+			thread->Start.entry_point = (Thread_Entry) func;
+			thread->Start.numeric_argument =
+			    (Thread_Entry_numeric_type) arg;
+			_Chain_Append_unprotected(
+			    &rtems_bsd_thread_delay_start_chain,
+			    &thread->Object.Node);
+		}
 
 		if (td_ptr != NULL) {
 			*td_ptr = td;




More information about the vc mailing list