ovs-rcu: Log a helpful warning when ovsrcu_synchronize() stalls.
[sliver-openvswitch.git] / lib / ovs-thread.c
index 3ca686f..19edf8f 100644 (file)
@@ -240,7 +240,10 @@ xpthread_barrier_wait(pthread_barrier_t *barrier)
 {
     int error;
 
+    ovsrcu_quiesce_start();
     error = pthread_barrier_wait(barrier);
+    ovsrcu_quiesce_end();
+
     if (error && OVS_UNLIKELY(error != PTHREAD_BARRIER_SERIAL_THREAD)) {
         ovs_abort(error, "pthread_barrier_wait failed");
     }
@@ -253,6 +256,7 @@ DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, 0);
 struct ovsthread_aux {
     void *(*start)(void *);
     void *arg;
+    char name[16];
 };
 
 static void *
@@ -270,13 +274,18 @@ ovsthread_wrapper(void *aux_)
     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);
     ovsrcu_quiesce_end();
+
     return aux.start(aux.arg);
 }
 
-void
-xpthread_create(pthread_t *threadp, pthread_attr_t *attr,
-                void *(*start)(void *), void *arg)
+/* Starts a thread that calls 'start(arg)'.  Sets the thread's name to 'name'
+ * (suffixed by its ovsthread_id()).  Returns the new thread's pthread_t. */
+pthread_t
+ovs_thread_create(const char *name, void *(*start)(void *), void *arg)
 {
     struct ovsthread_aux *aux;
     pthread_t thread;
@@ -289,12 +298,13 @@ xpthread_create(pthread_t *threadp, pthread_attr_t *attr,
     aux = xmalloc(sizeof *aux);
     aux->start = start;
     aux->arg = arg;
+    ovs_strlcpy(aux->name, name, sizeof aux->name);
 
-    error = pthread_create(threadp ? threadp : &thread, attr,
-                           ovsthread_wrapper, aux);
+    error = pthread_create(&thread, NULL, ovsthread_wrapper, aux);
     if (error) {
         ovs_abort(error, "pthread_create failed");
     }
+    return thread;
 }
 \f
 bool