mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 16:17:38 +00:00
lib/xref: use to transport thread_* file/line/func
Just a better way of doing what was previously the "debugargdef" macro. Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
b2fa8c0fa3
commit
60a3efec24
@ -74,7 +74,8 @@ int isis_run_dr(struct thread *thread)
|
||||
|
||||
if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
|
||||
zlog_warn("%s: scheduled for non broadcast circuit from %s:%d",
|
||||
__func__, thread->schedfrom, thread->schedfrom_line);
|
||||
__func__, thread->xref->xref.file,
|
||||
thread->xref->xref.line);
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,8 @@ static int frrzmq_read_msg(struct thread *t)
|
||||
if (read)
|
||||
frrzmq_check_events(cbp, &cb->write, ZMQ_POLLOUT);
|
||||
|
||||
funcname_thread_add_read_write(
|
||||
THREAD_READ, t->master, frrzmq_read_msg, cbp, cb->fd,
|
||||
&cb->read.thread, t->funcname, t->schedfrom, t->schedfrom_line);
|
||||
_thread_add_read_write(t->xref, t->master, frrzmq_read_msg, cbp,
|
||||
cb->fd, &cb->read.thread);
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
@ -148,14 +147,14 @@ out_err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int funcname_frrzmq_thread_add_read(struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*partfunc)(void *arg, void *zmqsock,
|
||||
zmq_msg_t *msg,
|
||||
unsigned partnum),
|
||||
void (*errfunc)(void *arg, void *zmqsock),
|
||||
void *arg, void *zmqsock,
|
||||
struct frrzmq_cb **cbp, debugargdef)
|
||||
int _frrzmq_thread_add_read(const struct xref_threadsched *xref,
|
||||
struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*partfunc)(void *arg, void *zmqsock,
|
||||
zmq_msg_t *msg, unsigned partnum),
|
||||
void (*errfunc)(void *arg, void *zmqsock),
|
||||
void *arg, void *zmqsock,
|
||||
struct frrzmq_cb **cbp)
|
||||
{
|
||||
int fd, events;
|
||||
size_t len;
|
||||
@ -192,13 +191,11 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master,
|
||||
if (events & ZMQ_POLLIN) {
|
||||
thread_cancel(&cb->read.thread);
|
||||
|
||||
funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd,
|
||||
&cb->read.thread, funcname, schedfrom,
|
||||
fromln);
|
||||
_thread_add_event(xref, master, frrzmq_read_msg, cbp, fd,
|
||||
&cb->read.thread);
|
||||
} else
|
||||
funcname_thread_add_read_write(
|
||||
THREAD_READ, master, frrzmq_read_msg, cbp, fd,
|
||||
&cb->read.thread, funcname, schedfrom, fromln);
|
||||
_thread_add_read_write(xref, master, frrzmq_read_msg, cbp, fd,
|
||||
&cb->read.thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -244,10 +241,8 @@ static int frrzmq_write_msg(struct thread *t)
|
||||
if (written)
|
||||
frrzmq_check_events(cbp, &cb->read, ZMQ_POLLIN);
|
||||
|
||||
funcname_thread_add_read_write(THREAD_WRITE, t->master,
|
||||
frrzmq_write_msg, cbp, cb->fd,
|
||||
&cb->write.thread, t->funcname,
|
||||
t->schedfrom, t->schedfrom_line);
|
||||
_thread_add_read_write(t->xref, t->master, frrzmq_write_msg, cbp,
|
||||
cb->fd, &cb->write.thread);
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
@ -257,11 +252,12 @@ out_err:
|
||||
cb->write.cb_error(cb->write.arg, cb->zmqsock);
|
||||
return 1;
|
||||
}
|
||||
int funcname_frrzmq_thread_add_write(struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*errfunc)(void *arg, void *zmqsock),
|
||||
void *arg, void *zmqsock,
|
||||
struct frrzmq_cb **cbp, debugargdef)
|
||||
|
||||
int _frrzmq_thread_add_write(const struct xref_threadsched *xref,
|
||||
struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*errfunc)(void *arg, void *zmqsock),
|
||||
void *arg, void *zmqsock, struct frrzmq_cb **cbp)
|
||||
{
|
||||
int fd, events;
|
||||
size_t len;
|
||||
@ -298,13 +294,11 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master,
|
||||
if (events & ZMQ_POLLOUT) {
|
||||
thread_cancel(&cb->write.thread);
|
||||
|
||||
funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd,
|
||||
&cb->write.thread, funcname,
|
||||
schedfrom, fromln);
|
||||
_thread_add_event(xref, master, frrzmq_write_msg, cbp, fd,
|
||||
&cb->write.thread);
|
||||
} else
|
||||
funcname_thread_add_read_write(
|
||||
THREAD_WRITE, master, frrzmq_write_msg, cbp, fd,
|
||||
&cb->write.thread, funcname, schedfrom, fromln);
|
||||
_thread_add_read_write(xref, master, frrzmq_write_msg, cbp, fd,
|
||||
&cb->write.thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -67,18 +67,32 @@ extern void *frrzmq_context;
|
||||
extern void frrzmq_init(void);
|
||||
extern void frrzmq_finish(void);
|
||||
|
||||
#define debugargdef const char *funcname, const char *schedfrom, int fromln
|
||||
#define _xref_zmq_a(type, f, d, call) \
|
||||
({ \
|
||||
static const struct xref_threadsched _xref \
|
||||
__attribute__((used)) = { \
|
||||
.xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
|
||||
.funcname = #f, \
|
||||
.dest = #d, \
|
||||
.thread_type = THREAD_ ## type, \
|
||||
}; \
|
||||
XREF_LINK(_xref.xref); \
|
||||
call; \
|
||||
}) \
|
||||
/* end */
|
||||
|
||||
/* core event registration, one of these 2 macros should be used */
|
||||
#define frrzmq_thread_add_read_msg(m, f, e, a, z, d) \
|
||||
funcname_frrzmq_thread_add_read(m, f, NULL, e, a, z, d, #f, __FILE__, \
|
||||
__LINE__)
|
||||
_xref_zmq_a(READ, f, d, \
|
||||
_frrzmq_thread_add_read(&_xref, m, f, NULL, e, a, z, d))
|
||||
|
||||
#define frrzmq_thread_add_read_part(m, f, e, a, z, d) \
|
||||
funcname_frrzmq_thread_add_read(m, NULL, f, e, a, z, d, #f, __FILE__, \
|
||||
__LINE__)
|
||||
_xref_zmq_a(READ, f, d, \
|
||||
_frrzmq_thread_add_read(&_xref, m, NULL, f, e, a, z, d))
|
||||
|
||||
#define frrzmq_thread_add_write_msg(m, f, e, a, z, d) \
|
||||
funcname_frrzmq_thread_add_write(m, f, e, a, z, d, #f, __FILE__, \
|
||||
__LINE__)
|
||||
_xref_zmq_a(WRITE, f, d, \
|
||||
_frrzmq_thread_add_write(&_xref, m, f, e, a, z, d))
|
||||
|
||||
struct cb_core;
|
||||
struct frrzmq_cb;
|
||||
@ -104,16 +118,18 @@ struct frrzmq_cb;
|
||||
* may schedule the event to run as soon as libfrr is back in its main
|
||||
* loop.
|
||||
*/
|
||||
extern int funcname_frrzmq_thread_add_read(
|
||||
struct thread_master *master, void (*msgfunc)(void *arg, void *zmqsock),
|
||||
extern int _frrzmq_thread_add_read(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*partfunc)(void *arg, void *zmqsock, zmq_msg_t *msg,
|
||||
unsigned partnum),
|
||||
void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
|
||||
struct frrzmq_cb **cb, debugargdef);
|
||||
extern int funcname_frrzmq_thread_add_write(
|
||||
struct thread_master *master, void (*msgfunc)(void *arg, void *zmqsock),
|
||||
struct frrzmq_cb **cb);
|
||||
extern int _frrzmq_thread_add_write(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
void (*msgfunc)(void *arg, void *zmqsock),
|
||||
void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
|
||||
struct frrzmq_cb **cb, debugargdef);
|
||||
struct frrzmq_cb **cb);
|
||||
|
||||
extern void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core);
|
||||
|
||||
|
10
lib/log.c
10
lib/log.c
@ -161,8 +161,9 @@ void zlog_signal(int signo, const char *action, void *siginfo_v,
|
||||
if (!tc)
|
||||
bprintfrr(&fb, "no thread information available\n");
|
||||
else
|
||||
bprintfrr(&fb, "in thread %s scheduled from %s:%d\n",
|
||||
tc->funcname, tc->schedfrom, tc->schedfrom_line);
|
||||
bprintfrr(&fb, "in thread %s scheduled from %s:%d %s()\n",
|
||||
tc->xref->funcname, tc->xref->xref.file,
|
||||
tc->xref->xref.line, tc->xref->xref.func);
|
||||
|
||||
zlog_sigsafe(fb.buf, fb.pos - fb.buf);
|
||||
}
|
||||
@ -300,8 +301,9 @@ void zlog_thread_info(int log_level)
|
||||
|
||||
if (tc)
|
||||
zlog(log_level,
|
||||
"Current thread function %s, scheduled from file %s, line %u",
|
||||
tc->funcname, tc->schedfrom, tc->schedfrom_line);
|
||||
"Current thread function %s, scheduled from file %s, line %u in %s()",
|
||||
tc->xref->funcname, tc->xref->xref.file,
|
||||
tc->xref->xref.line, tc->xref->xref.func);
|
||||
else
|
||||
zlog(log_level, "Current thread not known/applicable");
|
||||
}
|
||||
|
96
lib/thread.c
96
lib/thread.c
@ -342,7 +342,7 @@ static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
|
||||
if (!thread)
|
||||
vty_out(vty, "ERROR ");
|
||||
else
|
||||
vty_out(vty, "%s ", thread->funcname);
|
||||
vty_out(vty, "%s ", thread->xref->funcname);
|
||||
} else
|
||||
vty_out(vty, " ");
|
||||
|
||||
@ -352,7 +352,7 @@ static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
|
||||
if (!thread)
|
||||
vty_out(vty, "ERROR\n");
|
||||
else
|
||||
vty_out(vty, "%s\n", thread->funcname);
|
||||
vty_out(vty, "%s\n", thread->xref->funcname);
|
||||
} else
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
@ -678,7 +678,7 @@ char *thread_timer_to_hhmmss(char *buf, int buf_size,
|
||||
/* Get new thread. */
|
||||
static struct thread *thread_get(struct thread_master *m, uint8_t type,
|
||||
int (*func)(struct thread *), void *arg,
|
||||
debugargdef)
|
||||
const struct xref_threadsched *xref)
|
||||
{
|
||||
struct thread *thread = thread_list_pop(&m->unuse);
|
||||
struct cpu_thread_history tmp;
|
||||
@ -707,18 +707,17 @@ static struct thread *thread_get(struct thread_master *m, uint8_t type,
|
||||
* This hopefully saves us some serious
|
||||
* hash_get lookups.
|
||||
*/
|
||||
if (thread->funcname != funcname || thread->func != func) {
|
||||
if ((thread->xref && thread->xref->funcname != xref->funcname)
|
||||
|| thread->func != func) {
|
||||
tmp.func = func;
|
||||
tmp.funcname = funcname;
|
||||
tmp.funcname = xref->funcname;
|
||||
thread->hist =
|
||||
hash_get(m->cpu_record, &tmp,
|
||||
(void *(*)(void *))cpu_record_hash_alloc);
|
||||
}
|
||||
thread->hist->total_active++;
|
||||
thread->func = func;
|
||||
thread->funcname = funcname;
|
||||
thread->schedfrom = schedfrom;
|
||||
thread->schedfrom_line = fromln;
|
||||
thread->xref = xref;
|
||||
|
||||
return thread;
|
||||
}
|
||||
@ -832,12 +831,12 @@ done:
|
||||
}
|
||||
|
||||
/* Add new read thread. */
|
||||
struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, int fd,
|
||||
struct thread **t_ptr,
|
||||
debugargdef)
|
||||
struct thread *_thread_add_read_write(const struct xref_threadsched *xref,
|
||||
struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, int fd, struct thread **t_ptr)
|
||||
{
|
||||
int dir = xref->thread_type;
|
||||
struct thread *thread = NULL;
|
||||
struct thread **thread_array;
|
||||
|
||||
@ -882,7 +881,7 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
|
||||
/* make sure we have room for this fd + pipe poker fd */
|
||||
assert(queuepos + 1 < m->handler.pfdsize);
|
||||
|
||||
thread = thread_get(m, dir, func, arg, debugargpass);
|
||||
thread = thread_get(m, dir, func, arg, xref);
|
||||
|
||||
m->handler.pfds[queuepos].fd = fd;
|
||||
m->handler.pfds[queuepos].events |=
|
||||
@ -910,10 +909,10 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
|
||||
}
|
||||
|
||||
static struct thread *
|
||||
funcname_thread_add_timer_timeval(struct thread_master *m,
|
||||
int (*func)(struct thread *), int type,
|
||||
void *arg, struct timeval *time_relative,
|
||||
struct thread **t_ptr, debugargdef)
|
||||
_thread_add_timer_timeval(const struct xref_threadsched *xref,
|
||||
struct thread_master *m, int (*func)(struct thread *),
|
||||
int type, void *arg, struct timeval *time_relative,
|
||||
struct thread **t_ptr)
|
||||
{
|
||||
struct thread *thread;
|
||||
|
||||
@ -930,7 +929,7 @@ funcname_thread_add_timer_timeval(struct thread_master *m,
|
||||
/* thread is already scheduled; don't reschedule */
|
||||
return NULL;
|
||||
|
||||
thread = thread_get(m, type, func, arg, debugargpass);
|
||||
thread = thread_get(m, type, func, arg, xref);
|
||||
|
||||
frr_with_mutex(&thread->mtx) {
|
||||
monotime(&thread->u.sands);
|
||||
@ -951,10 +950,10 @@ funcname_thread_add_timer_timeval(struct thread_master *m,
|
||||
|
||||
|
||||
/* Add timer event thread. */
|
||||
struct thread *funcname_thread_add_timer(struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, long timer,
|
||||
struct thread **t_ptr, debugargdef)
|
||||
struct thread *_thread_add_timer(const struct xref_threadsched *xref,
|
||||
struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, long timer, struct thread **t_ptr)
|
||||
{
|
||||
struct timeval trel;
|
||||
|
||||
@ -963,16 +962,16 @@ struct thread *funcname_thread_add_timer(struct thread_master *m,
|
||||
trel.tv_sec = timer;
|
||||
trel.tv_usec = 0;
|
||||
|
||||
return funcname_thread_add_timer_timeval(m, func, THREAD_TIMER, arg,
|
||||
&trel, t_ptr, debugargpass);
|
||||
return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg,
|
||||
&trel, t_ptr);
|
||||
}
|
||||
|
||||
/* Add timer event thread with "millisecond" resolution */
|
||||
struct thread *funcname_thread_add_timer_msec(struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, long timer,
|
||||
struct thread **t_ptr,
|
||||
debugargdef)
|
||||
struct thread *_thread_add_timer_msec(const struct xref_threadsched *xref,
|
||||
struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, long timer,
|
||||
struct thread **t_ptr)
|
||||
{
|
||||
struct timeval trel;
|
||||
|
||||
@ -981,25 +980,26 @@ struct thread *funcname_thread_add_timer_msec(struct thread_master *m,
|
||||
trel.tv_sec = timer / 1000;
|
||||
trel.tv_usec = 1000 * (timer % 1000);
|
||||
|
||||
return funcname_thread_add_timer_timeval(m, func, THREAD_TIMER, arg,
|
||||
&trel, t_ptr, debugargpass);
|
||||
return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg,
|
||||
&trel, t_ptr);
|
||||
}
|
||||
|
||||
/* Add timer event thread with "millisecond" resolution */
|
||||
struct thread *funcname_thread_add_timer_tv(struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, struct timeval *tv,
|
||||
struct thread **t_ptr, debugargdef)
|
||||
struct thread *_thread_add_timer_tv(const struct xref_threadsched *xref,
|
||||
struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, struct timeval *tv,
|
||||
struct thread **t_ptr)
|
||||
{
|
||||
return funcname_thread_add_timer_timeval(m, func, THREAD_TIMER, arg, tv,
|
||||
t_ptr, debugargpass);
|
||||
return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg, tv,
|
||||
t_ptr);
|
||||
}
|
||||
|
||||
/* Add simple event thread. */
|
||||
struct thread *funcname_thread_add_event(struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, int val,
|
||||
struct thread **t_ptr, debugargdef)
|
||||
struct thread *_thread_add_event(const struct xref_threadsched *xref,
|
||||
struct thread_master *m,
|
||||
int (*func)(struct thread *),
|
||||
void *arg, int val, struct thread **t_ptr)
|
||||
{
|
||||
struct thread *thread = NULL;
|
||||
|
||||
@ -1013,7 +1013,7 @@ struct thread *funcname_thread_add_event(struct thread_master *m,
|
||||
/* thread is already scheduled; don't reschedule */
|
||||
break;
|
||||
|
||||
thread = thread_get(m, THREAD_EVENT, func, arg, debugargpass);
|
||||
thread = thread_get(m, THREAD_EVENT, func, arg, xref);
|
||||
frr_with_mutex(&thread->mtx) {
|
||||
thread->u.val = val;
|
||||
thread_list_add_tail(&m->event, thread);
|
||||
@ -1724,7 +1724,7 @@ void thread_call(struct thread *thread)
|
||||
flog_warn(
|
||||
EC_LIB_SLOW_THREAD,
|
||||
"SLOW THREAD: task %s (%lx) ran for %lums (cpu time %lums)",
|
||||
thread->funcname, (unsigned long)thread->func,
|
||||
thread->xref->funcname, (unsigned long)thread->func,
|
||||
realtime / 1000, cputime / 1000);
|
||||
}
|
||||
#endif /* CONSUMED_TIME_CHECK */
|
||||
@ -1732,15 +1732,15 @@ void thread_call(struct thread *thread)
|
||||
}
|
||||
|
||||
/* Execute thread */
|
||||
void funcname_thread_execute(struct thread_master *m,
|
||||
int (*func)(struct thread *), void *arg, int val,
|
||||
debugargdef)
|
||||
void _thread_execute(const struct xref_threadsched *xref,
|
||||
struct thread_master *m, int (*func)(struct thread *),
|
||||
void *arg, int val)
|
||||
{
|
||||
struct thread *thread;
|
||||
|
||||
/* Get or allocate new thread to execute. */
|
||||
frr_with_mutex(&m->mtx) {
|
||||
thread = thread_get(m, THREAD_EVENT, func, arg, debugargpass);
|
||||
thread = thread_get(m, THREAD_EVENT, func, arg, xref);
|
||||
|
||||
/* Set its event value. */
|
||||
frr_with_mutex(&thread->mtx) {
|
||||
|
104
lib/thread.h
104
lib/thread.h
@ -27,6 +27,7 @@
|
||||
#include "monotime.h"
|
||||
#include "frratomic.h"
|
||||
#include "typesafe.h"
|
||||
#include "xref.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -66,6 +67,14 @@ struct cancel_req {
|
||||
struct thread **threadref;
|
||||
};
|
||||
|
||||
struct xref_threadsched {
|
||||
struct xref xref;
|
||||
|
||||
const char *funcname;
|
||||
const char *dest;
|
||||
uint32_t thread_type;
|
||||
};
|
||||
|
||||
/* Master of the theads. */
|
||||
struct thread_master {
|
||||
char *name;
|
||||
@ -107,9 +116,7 @@ struct thread {
|
||||
struct timeval real;
|
||||
struct cpu_thread_history *hist; /* cache pointer to cpu_history */
|
||||
unsigned long yield; /* yield time in microseconds */
|
||||
const char *funcname; /* name of thread function */
|
||||
const char *schedfrom; /* source file thread was scheduled from */
|
||||
int schedfrom_line; /* line number of source file */
|
||||
const struct xref_threadsched *xref; /* origin location */
|
||||
pthread_mutex_t mtx; /* mutex for thread.c functions */
|
||||
};
|
||||
|
||||
@ -156,17 +163,45 @@ struct cpu_thread_history {
|
||||
thread_cancel(&(thread)); \
|
||||
} while (0)
|
||||
|
||||
#define debugargdef const char *funcname, const char *schedfrom, int fromln
|
||||
/*
|
||||
* Macro wrappers to generate xrefs for all thread add calls. Includes
|
||||
* file/line/function info for debugging/tracing.
|
||||
*/
|
||||
#include "lib/xref.h"
|
||||
|
||||
#define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_add_write(m,f,a,v,t) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_add_timer(m,f,a,v,t) funcname_thread_add_timer(m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_add_timer_msec(m,f,a,v,t) funcname_thread_add_timer_msec(m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_add_timer_tv(m,f,a,v,t) funcname_thread_add_timer_tv(m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__)
|
||||
#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
|
||||
#define thread_execute_name(m, f, a, v, n) \
|
||||
funcname_thread_execute(m, f, a, v, n, __FILE__, __LINE__)
|
||||
#define _xref_t_a(addfn, type, m, f, a, v, t) \
|
||||
({ \
|
||||
static const struct xref_threadsched _xref \
|
||||
__attribute__((used)) = { \
|
||||
.xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
|
||||
.funcname = #f, \
|
||||
.dest = #t, \
|
||||
.thread_type = THREAD_ ## type, \
|
||||
}; \
|
||||
XREF_LINK(_xref.xref); \
|
||||
_thread_add_ ## addfn(&_xref, m, f, a, v, t); \
|
||||
}) \
|
||||
/* end */
|
||||
|
||||
#define thread_add_read(m,f,a,v,t) _xref_t_a(read_write, READ, m,f,a,v,t)
|
||||
#define thread_add_write(m,f,a,v,t) _xref_t_a(read_write, WRITE, m,f,a,v,t)
|
||||
#define thread_add_timer(m,f,a,v,t) _xref_t_a(timer, TIMER, m,f,a,v,t)
|
||||
#define thread_add_timer_msec(m,f,a,v,t) _xref_t_a(timer_msec, TIMER, m,f,a,v,t)
|
||||
#define thread_add_timer_tv(m,f,a,v,t) _xref_t_a(timer_tv, TIMER, m,f,a,v,t)
|
||||
#define thread_add_event(m,f,a,v,t) _xref_t_a(event, TIMER, m,f,a,v,t)
|
||||
|
||||
#define thread_execute(m,f,a,v) \
|
||||
({ \
|
||||
static const struct xref_threadsched _xref \
|
||||
__attribute__((used)) = { \
|
||||
.xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
|
||||
.funcname = #f, \
|
||||
.dest = NULL, \
|
||||
.thread_type = THREAD_EXECUTE, \
|
||||
}; \
|
||||
XREF_LINK(_xref.xref); \
|
||||
_thread_execute(&_xref, m, f, a, v); \
|
||||
}) /* end */
|
||||
|
||||
/* Prototypes. */
|
||||
extern struct thread_master *thread_master_create(const char *);
|
||||
@ -174,35 +209,30 @@ void thread_master_set_name(struct thread_master *master, const char *name);
|
||||
extern void thread_master_free(struct thread_master *);
|
||||
extern void thread_master_free_unused(struct thread_master *);
|
||||
|
||||
extern struct thread *
|
||||
funcname_thread_add_read_write(int dir, struct thread_master *,
|
||||
int (*)(struct thread *), void *, int,
|
||||
struct thread **, debugargdef);
|
||||
extern struct thread *_thread_add_read_write(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, int fd, struct thread **tref);
|
||||
|
||||
extern struct thread *funcname_thread_add_timer(struct thread_master *,
|
||||
int (*)(struct thread *),
|
||||
void *, long, struct thread **,
|
||||
debugargdef);
|
||||
extern struct thread *_thread_add_timer(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, long t, struct thread **tref);
|
||||
|
||||
extern struct thread *
|
||||
funcname_thread_add_timer_msec(struct thread_master *, int (*)(struct thread *),
|
||||
void *, long, struct thread **, debugargdef);
|
||||
extern struct thread *_thread_add_timer_msec(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, long t, struct thread **tref);
|
||||
|
||||
extern struct thread *funcname_thread_add_timer_tv(struct thread_master *,
|
||||
int (*)(struct thread *),
|
||||
void *, struct timeval *,
|
||||
struct thread **,
|
||||
debugargdef);
|
||||
extern struct thread *_thread_add_timer_tv(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, struct timeval *tv,
|
||||
struct thread **tref);
|
||||
|
||||
extern struct thread *funcname_thread_add_event(struct thread_master *,
|
||||
int (*)(struct thread *),
|
||||
void *, int, struct thread **,
|
||||
debugargdef);
|
||||
extern struct thread *_thread_add_event(
|
||||
const struct xref_threadsched *xref, struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, int val, struct thread **tref);
|
||||
|
||||
extern void funcname_thread_execute(struct thread_master *,
|
||||
int (*)(struct thread *), void *, int,
|
||||
debugargdef);
|
||||
#undef debugargdef
|
||||
extern void _thread_execute(const struct xref_threadsched *xref,
|
||||
struct thread_master *master,
|
||||
int (*fn)(struct thread *), void *arg, int val);
|
||||
|
||||
extern void thread_cancel(struct thread **event);
|
||||
extern void thread_cancel_async(struct thread_master *, struct thread **,
|
||||
|
@ -73,8 +73,7 @@ static int wheel_timer_thread(struct thread *t)
|
||||
|
||||
wheel = THREAD_ARG(t);
|
||||
|
||||
thread_execute_name(wheel->master, wheel_timer_thread_helper,
|
||||
wheel, 0, wheel->name);
|
||||
thread_execute(wheel->master, wheel_timer_thread_helper, wheel, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
enum xref_type {
|
||||
XREFT_NONE = 0,
|
||||
|
||||
XREFT_THREADSCHED = 0x100,
|
||||
};
|
||||
|
||||
/* struct xref is the "const" part; struct xrefdata is the writable part. */
|
||||
|
Loading…
Reference in New Issue
Block a user