]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: mt-safe tracebacks
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 15 Jun 2017 16:05:19 +0000 (16:05 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 29 Jun 2017 23:32:15 +0000 (23:32 +0000)
can't be using them statics anymore sonny

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/log.c
lib/thread.c
lib/thread.h

index a8b221fd64e1db192817fdf33769e6fe5be89e2a..1c61d72168ed35f507c360a14463bdade3157b1c 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -509,16 +509,18 @@ zlog_signal(int signo, const char *action
                        );
 
   s = buf;
-  if (!thread_current)
+  struct thread *tc;
+  tc = pthread_getspecific (thread_current);
+  if (!tc)
     s = str_append (LOC, "no thread information available\n");
   else
     {
       s = str_append (LOC, "in thread ");
-      s = str_append (LOC, thread_current->funcname);
+      s = str_append (LOC, tc->funcname);
       s = str_append (LOC, " scheduled from ");
-      s = str_append (LOC, thread_current->schedfrom);
+      s = str_append (LOC, tc->schedfrom);
       s = str_append (LOC, ":");
-      s = num_append (LOC, thread_current->schedfrom_line);
+      s = num_append (LOC, tc->schedfrom_line);
       s = str_append (LOC, "\n");
     }
 
@@ -700,10 +702,13 @@ ZLOG_FUNC(zlog_debug, LOG_DEBUG)
 
 void zlog_thread_info (int log_level)
 {
-  if (thread_current)
+  struct thread *tc;
+  tc = pthread_getspecific (thread_current);
+
+  if (tc)
     zlog(log_level, "Current thread function %s, scheduled from "
-        "file %s, line %u", thread_current->funcname,
-        thread_current->schedfrom, thread_current->schedfrom_line);
+        "file %s, line %u", tc->funcname,
+        tc->schedfrom, tc->schedfrom_line);
   else
     zlog(log_level, "Current thread not known/applicable");
 }
index 335e7fc0445a3649fae4885a1904044d19daa3f3..feeffd31e81bf8fb788916c62c8c955981000c86 100644 (file)
@@ -47,8 +47,10 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS,  "Thread stats")
       write (m->io_pipe[1], &wakebyte, 1); \
   } while (0);
 
+pthread_once_t init_once = PTHREAD_ONCE_INIT;
 static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
 static struct hash *cpu_record = NULL;
+pthread_key_t thread_current;
 
 static unsigned long
 timeval_elapsed (struct timeval a, struct timeval b)
@@ -334,6 +336,17 @@ cancelreq_del (void *cr)
   XFREE (MTYPE_TMP, cr);
 }
 
+/* initializer, only ever called once */
+static void initializer ()
+{
+  if (cpu_record == NULL)
+    cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
+                              (int (*) (const void *, const void *))
+                              cpu_record_hash_cmp);
+
+  pthread_key_create (&thread_current, NULL);
+}
+
 /* Allocate new thread master.  */
 struct thread_master *
 thread_master_create (void)
@@ -343,14 +356,7 @@ thread_master_create (void)
 
   getrlimit(RLIMIT_NOFILE, &limit);
 
-  pthread_mutex_lock (&cpu_record_mtx);
-  {
-    if (cpu_record == NULL)
-      cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
-                                (int (*) (const void *, const void *))
-                                cpu_record_hash_cmp);
-  }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  pthread_once (&init_once, &initializer);
 
   rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
   if (rv == NULL)
@@ -1096,6 +1102,7 @@ thread_cancel (struct thread *thread)
     listnode_add (thread->master->cancel_req, cr);
     do_thread_cancel (thread->master);
   }
+done:
   pthread_mutex_unlock (&thread->master->mtx);
 }
 
@@ -1449,8 +1456,6 @@ thread_getrusage (RUSAGE_T *r)
   getrusage(RUSAGE_SELF, &(r->cpu));
 }
 
-struct thread *thread_current = NULL;
-
 /* We check thread consumed time. If the system has getrusage, we'll
    use that to get in-depth stats on the performance of the thread in addition
    to wall clock time stats from gettimeofday. */
@@ -1463,9 +1468,9 @@ thread_call (struct thread *thread)
   GETRUSAGE (&before);
   thread->real = before.real;
 
-  thread_current = thread;
+  pthread_setspecific (thread_current, thread);
   (*thread->func) (thread);
-  thread_current = NULL;
+  pthread_setspecific (thread_current, NULL);
 
   GETRUSAGE (&after);
 
index e48068b174e5a38f9986dcc036edc078af645106..1760a930f9a59e84e9fb93b2f9c561a20e4d10b9 100644 (file)
@@ -220,6 +220,6 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
                                          unsigned long *cpu_time_elapsed);
 
 /* only for use in logging functions! */
-extern struct thread *thread_current;
+extern pthread_key_t thread_current;
 
 #endif /* _ZEBRA_THREAD_H */