struct cpu_thread_history *new;
new = XCALLOC (MTYPE_THREAD_STATS, sizeof (struct cpu_thread_history));
new->func = a->func;
- strcpy(new->funcname, a->funcname);
+ new->funcname = a->funcname;
return new;
}
void *args[3] = {&tmp, vty, &filter};
memset(&tmp, 0, sizeof tmp);
- strcpy(tmp.funcname, "TOTAL");
+ tmp.funcname = "TOTAL";
tmp.types = filter;
#ifdef HAVE_RUSAGE
assert (thread->prev == NULL);
assert (thread->type == THREAD_UNUSED);
thread_list_add (&m->unuse, thread);
- /* XXX: Should we deallocate funcname here? */
}
/* Free all unused thread. */
return 0;
}
-/* Trim blankspace and "()"s */
-static void
-strip_funcname (char *dest, const char *funcname)
-{
- char buff[FUNCNAME_LEN];
- char tmp, *e, *b = buff;
-
- strncpy(buff, funcname, sizeof(buff));
- buff[ sizeof(buff) -1] = '\0';
- e = buff +strlen(buff) -1;
-
- /* Wont work for funcname == "Word (explanation)" */
-
- while (*b == ' ' || *b == '(')
- ++b;
- while (*e == ' ' || *e == ')')
- --e;
- e++;
-
- tmp = *e;
- *e = '\0';
- strcpy (dest, b);
- *e = tmp;
-}
+#define debugargdef const char *funcname, const char *schedfrom, int fromln
+#define debugargpass funcname, schedfrom, fromln
struct timeval
thread_timer_remain(struct thread *thread)
/* Get new thread. */
static struct thread *
thread_get (struct thread_master *m, u_char type,
- int (*func) (struct thread *), void *arg, const char* funcname)
+ int (*func) (struct thread *), void *arg, debugargdef)
{
struct thread *thread = thread_trim_head (&m->unuse);
thread->index = -1;
thread->yield = THREAD_YIELD_TIME_SLOT; /* default */
- strip_funcname (thread->funcname, funcname);
+ thread->funcname = funcname;
+ thread->schedfrom = schedfrom;
+ thread->schedfrom_line = fromln;
return thread;
}
/* generic add thread function */
static struct thread *
generic_thread_add(struct thread_master *m, int (*func) (struct thread *),
- void *arg, int fd, const char* funcname, int dir)
+ void *arg, int fd, int dir, debugargdef)
{
struct thread *thread;
/* is there enough space for a new fd? */
assert (queuepos < m->handler.pfdsize);
- thread = thread_get (m, type, func, arg, funcname);
+ thread = thread_get (m, type, func, arg, funcname, debugargpass);
m->handler.pfds[queuepos].fd = fd;
m->handler.pfds[queuepos].events |= event;
if (queuepos == m->handler.pfdcount)
/* 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, const char* funcname)
+ int (*func) (struct thread *), void *arg, int fd,
+ debugargdef)
{
struct thread *thread = NULL;
#endif
#if defined (HAVE_POLL)
- thread = generic_thread_add(m, func, arg, fd, funcname, dir);
+ thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
if (thread == NULL)
return NULL;
}
FD_SET (fd, fdset);
- thread = thread_get (m, dir, func, arg, funcname);
+ thread = thread_get (m, dir, func, arg, debugargpass);
#endif
thread->u.fd = fd;
int (*func) (struct thread *),
int type,
void *arg,
- struct timeval *time_relative,
- const char* funcname)
+ struct timeval *time_relative,
+ debugargdef)
{
struct thread *thread;
struct pqueue *queue;
assert (time_relative);
queue = ((type == THREAD_TIMER) ? m->timer : m->background);
- thread = thread_get (m, type, func, arg, funcname);
+ thread = thread_get (m, type, func, arg, debugargpass);
/* Do we need jitter here? */
quagga_get_relative (NULL);
struct thread *
funcname_thread_add_timer (struct thread_master *m,
int (*func) (struct thread *),
- void *arg, long timer, const char* funcname)
+ void *arg, long timer,
+ debugargdef)
{
struct timeval trel;
trel.tv_usec = 0;
return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg,
- &trel, funcname);
+ &trel, debugargpass);
}
/* 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, const char* funcname)
+ void *arg, long timer,
+ debugargdef)
{
struct timeval trel;
trel.tv_usec = 1000*(timer % 1000);
return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER,
- arg, &trel, funcname);
+ arg, &trel, debugargpass);
}
/* Add a background thread, with an optional millisec delay */
struct thread *
funcname_thread_add_background (struct thread_master *m,
int (*func) (struct thread *),
- void *arg, long delay,
- const char *funcname)
+ void *arg, long delay,
+ debugargdef)
{
struct timeval trel;
}
return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND,
- arg, &trel, funcname);
+ arg, &trel, debugargpass);
}
/* Add simple event thread. */
struct thread *
funcname_thread_add_event (struct thread_master *m,
- int (*func) (struct thread *), void *arg, int val, const char* funcname)
+ int (*func) (struct thread *), void *arg, int val,
+ debugargdef)
{
struct thread *thread;
assert (m != NULL);
- thread = thread_get (m, THREAD_EVENT, func, arg, funcname);
+ thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
thread->u.val = val;
thread_list_add (&m->event, thread);
struct cpu_thread_history tmp;
tmp.func = thread->func;
- strcpy(tmp.funcname, thread->funcname);
+ tmp.funcname = thread->funcname;
thread->hist = hash_get (cpu_record, &tmp,
(void * (*) (void *))cpu_record_hash_alloc);
int (*func)(struct thread *),
void *arg,
int val,
- const char* funcname)
+ debugargdef)
{
struct thread dummy;
dummy.func = func;
dummy.arg = arg;
dummy.u.val = val;
- strip_funcname (dummy.funcname, funcname);
+
+ dummy.funcname = funcname;
+ dummy.schedfrom = schedfrom;
+ dummy.schedfrom_line = fromln;
+
thread_call (&dummy);
return NULL;
typedef unsigned char thread_type;
-/* ISO C99 maximum function name length is 63 */
-#define FUNCNAME_LEN 64
-
/* Thread itself. */
struct thread
{
struct timeval real;
struct cpu_thread_history *hist; /* cache pointer to cpu_history */
unsigned long yield; /* yield time in us */
- char funcname[FUNCNAME_LEN];
+ const char *funcname;
+ const char *schedfrom;
+ int schedfrom_line;
};
struct cpu_thread_history
struct time_stats cpu;
#endif
thread_type types;
- char funcname[FUNCNAME_LEN];
+ const char *funcname;
};
/* Clocks supported by Quagga */
#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
-#define thread_add_read(m,f,a,v) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,#f)
-#define thread_add_write(m,f,a,v) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,#f)
-#define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f)
-#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
-#define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
-#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
+#define debugargdef const char *funcname, const char *schedfrom, int fromln
+
+#define thread_add_read(m,f,a,v) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_write(m,f,a,v) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
/* The 4th arg to thread_add_background is the # of milliseconds to delay. */
-#define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f)
+#define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f,__FILE__,__LINE__)
/* Prototypes. */
extern struct thread_master *thread_master_create (void);
extern struct thread *funcname_thread_add_read_write (int dir, struct thread_master *,
int (*)(struct thread *),
- void *, int, const char*);
+ void *, int, debugargdef);
extern struct thread *funcname_thread_add_timer (struct thread_master *,
int (*)(struct thread *),
- void *, long, const char*);
+ void *, long, debugargdef);
extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
int (*)(struct thread *),
- void *, long, const char*);
+ void *, long, debugargdef);
extern struct thread *funcname_thread_add_event (struct thread_master *,
int (*)(struct thread *),
- void *, int, const char*);
+ void *, int, debugargdef);
extern struct thread *funcname_thread_add_background (struct thread_master *,
int (*func)(struct thread *),
void *arg,
long milliseconds_to_delay,
- const char *funcname);
+ debugargdef);
extern struct thread *funcname_thread_execute (struct thread_master *,
int (*)(struct thread *),
- void *, int, const char *);
+ void *, int, debugargdef);
+#undef debugargdef
+
extern void thread_cancel (struct thread *);
extern unsigned int thread_cancel_event (struct thread_master *, void *);
extern struct thread *thread_fetch (struct thread_master *, struct thread *);