This will be used by next commit Signed-off-by: Daniele Di Proietto <diproiet...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev