[ovs-dev] [seq 3/5] ovs-thread: New function ovsthread_id_self()

Ben Pfaff blp at nicira.com
Tue Aug 6 23:56:54 UTC 2013


Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/ovs-thread.c |   33 ++++++++++++++++++++++++++++++++-
 lib/ovs-thread.h |   17 +++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index d0ec9ec..055d66a 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -169,18 +169,49 @@ ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_)
         ovs_abort(error, "pthread_cond_wait failed");
     }
 }
+
+DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, 0);
+
+struct ovsthread_aux {
+    void *(*start)(void *);
+    void *arg;
+};
+
+static void *
+ovsthread_wrapper(void *aux_)
+{
+    static atomic_uint next_id = ATOMIC_VAR_INIT(1);
+
+    struct ovsthread_aux *auxp = aux_;
+    struct ovsthread_aux aux;
+    unsigned int id;
+
+    atomic_add(&next_id, 1, &id);
+    *ovsthread_id_get() = id;
+
+    aux = *auxp;
+    free(auxp);
+
+    return aux.start(aux.arg);
+}
 
 void
 xpthread_create(pthread_t *threadp, pthread_attr_t *attr,
                 void *(*start)(void *), void *arg)
 {
+    struct ovsthread_aux *aux;
     pthread_t thread;
     int error;
 
     forbid_forking("multiple threads exist");
     multithreaded = true;
 
-    error = pthread_create(threadp ? threadp : &thread, attr, start, arg);
+    aux = xmalloc(sizeof *aux);
+    aux->start = start;
+    aux->arg = arg;
+
+    error = pthread_create(threadp ? threadp : &thread, attr,
+                           ovsthread_wrapper, aux);
     if (error) {
         ovs_abort(error, "pthread_create failed");
     }
diff --git a/lib/ovs-thread.h b/lib/ovs-thread.h
index abe479a..e644832 100644
--- a/lib/ovs-thread.h
+++ b/lib/ovs-thread.h
@@ -501,6 +501,23 @@ ovsthread_once_start(struct ovsthread_once *once)
     ((ONCE)->done ? false : ({ OVS_MACRO_LOCK((&ONCE->mutex)); true; }))
 #endif
 
+/* Thread ID.
+ *
+ * pthread_t isn't so nice for some purposes.  Its size and representation are
+ * implementation dependent, which means that there is no way to hash it.
+ * This thread ID avoids the problem.
+ */
+
+DECLARE_EXTERN_PER_THREAD_DATA(unsigned int, ovsthread_id);
+
+/* Returns a per-thread identifier unique within the lifetime of the
+ * process. */
+static inline unsigned int
+ovsthread_id_self(void)
+{
+    return *ovsthread_id_get();
+}
+
 void assert_single_threaded_at(const char *where);
 #define assert_single_threaded() assert_single_threaded_at(SOURCE_LOCATOR)
 
-- 
1.7.10.4




More information about the dev mailing list