From e0bebc7c223abf239b5ccda1c2de42a2b0410455 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Thu, 15 Jun 2017 16:05:19 +0000 Subject: [PATCH] lib: mt-safe tracebacks can't be using them statics anymore sonny Signed-off-by: Quentin Young --- lib/log.c | 19 ++++++++++++------- lib/thread.c | 29 +++++++++++++++++------------ lib/thread.h | 2 +- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/lib/log.c b/lib/log.c index a8b221fd64..1c61d72168 100644 --- 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"); } diff --git a/lib/thread.c b/lib/thread.c index 335e7fc044..feeffd31e8 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -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); diff --git a/lib/thread.h b/lib/thread.h index e48068b174..1760a930f9 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -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 */ -- 2.39.5