lib: mt-safe tracebacks

can't be using them statics anymore sonny

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2017-06-15 16:05:19 +00:00
parent 0693f6fc75
commit e0bebc7c22
3 changed files with 30 additions and 20 deletions

View File

@ -509,16 +509,18 @@ zlog_signal(int signo, const char *action
); );
s = buf; s = buf;
if (!thread_current) struct thread *tc;
tc = pthread_getspecific (thread_current);
if (!tc)
s = str_append (LOC, "no thread information available\n"); s = str_append (LOC, "no thread information available\n");
else else
{ {
s = str_append (LOC, "in thread "); 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, " scheduled from ");
s = str_append (LOC, thread_current->schedfrom); s = str_append (LOC, tc->schedfrom);
s = str_append (LOC, ":"); s = str_append (LOC, ":");
s = num_append (LOC, thread_current->schedfrom_line); s = num_append (LOC, tc->schedfrom_line);
s = str_append (LOC, "\n"); s = str_append (LOC, "\n");
} }
@ -700,10 +702,13 @@ ZLOG_FUNC(zlog_debug, LOG_DEBUG)
void zlog_thread_info (int log_level) 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 " zlog(log_level, "Current thread function %s, scheduled from "
"file %s, line %u", thread_current->funcname, "file %s, line %u", tc->funcname,
thread_current->schedfrom, thread_current->schedfrom_line); tc->schedfrom, tc->schedfrom_line);
else else
zlog(log_level, "Current thread not known/applicable"); zlog(log_level, "Current thread not known/applicable");
} }

View File

@ -47,8 +47,10 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats")
write (m->io_pipe[1], &wakebyte, 1); \ write (m->io_pipe[1], &wakebyte, 1); \
} while (0); } while (0);
pthread_once_t init_once = PTHREAD_ONCE_INIT;
static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct hash *cpu_record = NULL; static struct hash *cpu_record = NULL;
pthread_key_t thread_current;
static unsigned long static unsigned long
timeval_elapsed (struct timeval a, struct timeval b) timeval_elapsed (struct timeval a, struct timeval b)
@ -334,6 +336,17 @@ cancelreq_del (void *cr)
XFREE (MTYPE_TMP, 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. */ /* Allocate new thread master. */
struct thread_master * struct thread_master *
thread_master_create (void) thread_master_create (void)
@ -343,14 +356,7 @@ thread_master_create (void)
getrlimit(RLIMIT_NOFILE, &limit); getrlimit(RLIMIT_NOFILE, &limit);
pthread_mutex_lock (&cpu_record_mtx); pthread_once (&init_once, &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_mutex_unlock (&cpu_record_mtx);
rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master)); rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
if (rv == NULL) if (rv == NULL)
@ -1096,6 +1102,7 @@ thread_cancel (struct thread *thread)
listnode_add (thread->master->cancel_req, cr); listnode_add (thread->master->cancel_req, cr);
do_thread_cancel (thread->master); do_thread_cancel (thread->master);
} }
done:
pthread_mutex_unlock (&thread->master->mtx); pthread_mutex_unlock (&thread->master->mtx);
} }
@ -1449,8 +1456,6 @@ thread_getrusage (RUSAGE_T *r)
getrusage(RUSAGE_SELF, &(r->cpu)); getrusage(RUSAGE_SELF, &(r->cpu));
} }
struct thread *thread_current = NULL;
/* We check thread consumed time. If the system has getrusage, we'll /* 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 use that to get in-depth stats on the performance of the thread in addition
to wall clock time stats from gettimeofday. */ to wall clock time stats from gettimeofday. */
@ -1463,9 +1468,9 @@ thread_call (struct thread *thread)
GETRUSAGE (&before); GETRUSAGE (&before);
thread->real = before.real; thread->real = before.real;
thread_current = thread; pthread_setspecific (thread_current, thread);
(*thread->func) (thread); (*thread->func) (thread);
thread_current = NULL; pthread_setspecific (thread_current, NULL);
GETRUSAGE (&after); GETRUSAGE (&after);

View File

@ -220,6 +220,6 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
unsigned long *cpu_time_elapsed); unsigned long *cpu_time_elapsed);
/* only for use in logging functions! */ /* only for use in logging functions! */
extern struct thread *thread_current; extern pthread_key_t thread_current;
#endif /* _ZEBRA_THREAD_H */ #endif /* _ZEBRA_THREAD_H */