mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 03:47:47 +00:00
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:
parent
0693f6fc75
commit
e0bebc7c22
19
lib/log.c
19
lib/log.c
@ -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");
|
||||||
}
|
}
|
||||||
|
29
lib/thread.c
29
lib/thread.c
@ -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);
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user