[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