[ovs-dev] [PATCH 3/6] ovs-thread: Keep a list of all threads.

Daniele Di Proietto diproiettod at vmware.com
Thu Mar 12 18:04:34 UTC 2015


This will be used by next commit

Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
---
 lib/ovs-thread.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 lib/ovs-thread.h | 13 +++++++++++++
 2 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index 7d38c80..fe6a853 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -308,35 +308,38 @@ ovs_barrier_block(struct ovs_barrier *barrier)
 
 DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, 0);
 
-struct ovsthread_aux {
-    void *(*start)(void *);
-    void *arg;
-    char name[16];
-};
+struct ovs_mutex ovsthread_list_mutex = OVS_MUTEX_INITIALIZER;
+/* list of all running threads */
+struct ovs_list ovsthread_list OVS_GUARDED_BY(ovsthread_list_mutex) =
+    OVS_LIST_INITIALIZER(&ovsthread_list);
 
 static void *
 ovsthread_wrapper(void *aux_)
 {
     static atomic_count next_id = ATOMIC_COUNT_INIT(1);
-
-    struct ovsthread_aux *auxp = aux_;
-    struct ovsthread_aux aux;
+    struct ovsthread *aux = aux_;
     unsigned int id;
+    void *ret;
 
     id = atomic_count_inc(&next_id);
     *ovsthread_id_get() = id;
 
-    aux = *auxp;
-    free(auxp);
-
     /* The order of the following calls is important, because
      * ovsrcu_quiesce_end() saves a copy of the thread name. */
-    set_subprogram_name("%s%u", aux.name, id);
+    set_subprogram_name("%s%u", aux->name, id);
     ovsrcu_quiesce_end();
 
     thread_set_nonpmd();
 
-    return aux.start(aux.arg);
+    ret = aux->start(aux->arg);
+
+    ovs_mutex_lock(&ovsthread_list_mutex);
+    list_remove(&aux->list_node);
+    ovs_mutex_unlock(&ovsthread_list_mutex);
+
+    free(aux);
+
+    return ret;
 }
 
 /* Starts a thread that calls 'start(arg)'.  Sets the thread's name to 'name'
@@ -344,10 +347,25 @@ ovsthread_wrapper(void *aux_)
 pthread_t
 ovs_thread_create(const char *name, void *(*start)(void *), void *arg)
 {
-    struct ovsthread_aux *aux;
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+    struct ovsthread *aux;
     pthread_t thread;
     int error;
 
+    if (ovsthread_once_start(&once)) {
+        /* Inserts the main thread in the thread list */
+        static struct ovsthread main_thread;
+
+        ovs_strlcpy(main_thread.name, get_subprogram_name(),
+                    sizeof main_thread.name);
+        main_thread.thread = pthread_self();
+
+        ovs_mutex_lock(&ovsthread_list_mutex);
+        list_insert(&ovsthread_list, &main_thread.list_node);
+        ovs_mutex_unlock(&ovsthread_list_mutex);
+
+        ovsthread_once_done(&once);
+    }
     forbid_forking("multiple threads exist");
     multithreaded = true;
     ovsrcu_quiesce_end();
@@ -357,10 +375,14 @@ ovs_thread_create(const char *name, void *(*start)(void *), void *arg)
     aux->arg = arg;
     ovs_strlcpy(aux->name, name, sizeof aux->name);
 
+    ovs_mutex_lock(&ovsthread_list_mutex);
     error = pthread_create(&thread, NULL, ovsthread_wrapper, aux);
     if (error) {
         ovs_abort(error, "pthread_create failed");
     }
+    aux->thread = thread;
+    list_insert(&ovsthread_list, &aux->list_node);
+    ovs_mutex_unlock(&ovsthread_list_mutex);
     return thread;
 }
 
@@ -773,4 +795,5 @@ ovsthread_getspecific(ovsthread_key_t key)
 {
     return *ovsthread_key_lookup__(key);
 }
+
 #endif
diff --git a/lib/ovs-thread.h b/lib/ovs-thread.h
index 26b2ccd..5f49a1d 100644
--- a/lib/ovs-thread.h
+++ b/lib/ovs-thread.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include "ovs-atomic.h"
 #include "openvswitch/thread.h"
+#include "openvswitch/list.h"
 #include "util.h"
 
 struct seq;
@@ -520,6 +521,18 @@ pid_t xfork_at(const char *where);
 void forbid_forking(const char *reason);
 bool may_fork(void);
 
+extern struct ovs_mutex ovsthread_list_mutex;
+/* list of all running threads. Protected by ovsthread_list_mutex */
+extern struct ovs_list ovsthread_list OVS_GUARDED_BY(ovsthread_list_mutex);
+
+struct ovsthread {
+    void *(*start)(void *);
+    void *arg;
+    char name[16];
+    struct ovs_list list_node; /* in 'thread_list' */
+    pthread_t thread;
+};
+
 /* Useful functions related to threading. */
 
 int count_cpu_cores(void);
-- 
2.1.4




More information about the dev mailing list