mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 06:29:40 +00:00
lib: do not allocate/free thread funcnames
This avoids memory heap fragmentation and imposses less load on the system memory allocator. * thread.h: FUNCNAME_LEN defined to 64 (ISO C99 says max 63) Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net> [changed FUNCNAME_LEN to a less arbitrary value] Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
64018324d5
commit
22714f99c4
@ -21,7 +21,6 @@ struct memory_list memory_list_lib[] =
|
|||||||
{ MTYPE_THREAD, "Thread" },
|
{ MTYPE_THREAD, "Thread" },
|
||||||
{ MTYPE_THREAD_MASTER, "Thread master" },
|
{ MTYPE_THREAD_MASTER, "Thread master" },
|
||||||
{ MTYPE_THREAD_STATS, "Thread stats" },
|
{ MTYPE_THREAD_STATS, "Thread stats" },
|
||||||
{ MTYPE_THREAD_FUNCNAME, "Thread function name" },
|
|
||||||
{ MTYPE_VTY, "VTY" },
|
{ MTYPE_VTY, "VTY" },
|
||||||
{ MTYPE_VTY_OUT_BUF, "VTY output buffer" },
|
{ MTYPE_VTY_OUT_BUF, "VTY output buffer" },
|
||||||
{ MTYPE_VTY_HIST, "VTY history" },
|
{ MTYPE_VTY_HIST, "VTY history" },
|
||||||
|
37
lib/thread.c
37
lib/thread.c
@ -235,7 +235,7 @@ cpu_record_hash_alloc (struct cpu_thread_history *a)
|
|||||||
struct cpu_thread_history *new;
|
struct cpu_thread_history *new;
|
||||||
new = XCALLOC (MTYPE_THREAD_STATS, sizeof (struct cpu_thread_history));
|
new = XCALLOC (MTYPE_THREAD_STATS, sizeof (struct cpu_thread_history));
|
||||||
new->func = a->func;
|
new->func = a->func;
|
||||||
new->funcname = XSTRDUP(MTYPE_THREAD_FUNCNAME, a->funcname);
|
strcpy(new->funcname, a->funcname);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +244,6 @@ cpu_record_hash_free (void *a)
|
|||||||
{
|
{
|
||||||
struct cpu_thread_history *hist = a;
|
struct cpu_thread_history *hist = a;
|
||||||
|
|
||||||
XFREE (MTYPE_THREAD_FUNCNAME, hist->funcname);
|
|
||||||
XFREE (MTYPE_THREAD_STATS, hist);
|
XFREE (MTYPE_THREAD_STATS, hist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +302,7 @@ cpu_record_print(struct vty *vty, thread_type filter)
|
|||||||
void *args[3] = {&tmp, vty, &filter};
|
void *args[3] = {&tmp, vty, &filter};
|
||||||
|
|
||||||
memset(&tmp, 0, sizeof tmp);
|
memset(&tmp, 0, sizeof tmp);
|
||||||
tmp.funcname = (char *)"TOTAL";
|
strcpy(tmp.funcname, "TOTAL");
|
||||||
tmp.types = filter;
|
tmp.types = filter;
|
||||||
|
|
||||||
#ifdef HAVE_RUSAGE
|
#ifdef HAVE_RUSAGE
|
||||||
@ -577,8 +576,6 @@ thread_list_free (struct thread_master *m, struct thread_list *list)
|
|||||||
for (t = list->head; t; t = next)
|
for (t = list->head; t; t = next)
|
||||||
{
|
{
|
||||||
next = t->next;
|
next = t->next;
|
||||||
if (t->funcname)
|
|
||||||
XFREE (MTYPE_THREAD_FUNCNAME, t->funcname);
|
|
||||||
XFREE (MTYPE_THREAD, t);
|
XFREE (MTYPE_THREAD, t);
|
||||||
list->count--;
|
list->count--;
|
||||||
m->alloc--;
|
m->alloc--;
|
||||||
@ -636,11 +633,11 @@ thread_timer_remain_second (struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Trim blankspace and "()"s */
|
/* Trim blankspace and "()"s */
|
||||||
static char *
|
void
|
||||||
strip_funcname (const char *funcname)
|
strip_funcname (char *dest, const char *funcname)
|
||||||
{
|
{
|
||||||
char buff[100];
|
char buff[FUNCNAME_LEN];
|
||||||
char tmp, *ret, *e, *b = buff;
|
char tmp, *e, *b = buff;
|
||||||
|
|
||||||
strncpy(buff, funcname, sizeof(buff));
|
strncpy(buff, funcname, sizeof(buff));
|
||||||
buff[ sizeof(buff) -1] = '\0';
|
buff[ sizeof(buff) -1] = '\0';
|
||||||
@ -656,10 +653,8 @@ strip_funcname (const char *funcname)
|
|||||||
|
|
||||||
tmp = *e;
|
tmp = *e;
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
ret = XSTRDUP (MTYPE_THREAD_FUNCNAME, b);
|
strcpy (dest, b);
|
||||||
*e = tmp;
|
*e = tmp;
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get new thread. */
|
/* Get new thread. */
|
||||||
@ -669,12 +664,7 @@ thread_get (struct thread_master *m, u_char type,
|
|||||||
{
|
{
|
||||||
struct thread *thread = thread_trim_head (&m->unuse);
|
struct thread *thread = thread_trim_head (&m->unuse);
|
||||||
|
|
||||||
if (thread)
|
if (! thread)
|
||||||
{
|
|
||||||
if (thread->funcname)
|
|
||||||
XFREE(MTYPE_THREAD_FUNCNAME, thread->funcname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
|
thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
|
||||||
m->alloc++;
|
m->alloc++;
|
||||||
@ -685,7 +675,7 @@ thread_get (struct thread_master *m, u_char type,
|
|||||||
thread->func = func;
|
thread->func = func;
|
||||||
thread->arg = arg;
|
thread->arg = arg;
|
||||||
|
|
||||||
thread->funcname = strip_funcname(funcname);
|
strip_funcname (thread->funcname, funcname);
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
@ -953,7 +943,6 @@ thread_run (struct thread_master *m, struct thread *thread,
|
|||||||
{
|
{
|
||||||
*fetch = *thread;
|
*fetch = *thread;
|
||||||
thread->type = THREAD_UNUSED;
|
thread->type = THREAD_UNUSED;
|
||||||
thread->funcname = NULL; /* thread_call will free fetch's copied pointer */
|
|
||||||
thread_add_unuse (m, thread);
|
thread_add_unuse (m, thread);
|
||||||
return fetch;
|
return fetch;
|
||||||
}
|
}
|
||||||
@ -1187,7 +1176,7 @@ thread_call (struct thread *thread)
|
|||||||
struct cpu_thread_history tmp;
|
struct cpu_thread_history tmp;
|
||||||
|
|
||||||
tmp.func = thread->func;
|
tmp.func = thread->func;
|
||||||
tmp.funcname = thread->funcname;
|
strcpy(tmp.funcname, thread->funcname);
|
||||||
|
|
||||||
thread->hist = hash_get (cpu_record, &tmp,
|
thread->hist = hash_get (cpu_record, &tmp,
|
||||||
(void * (*) (void *))cpu_record_hash_alloc);
|
(void * (*) (void *))cpu_record_hash_alloc);
|
||||||
@ -1227,8 +1216,6 @@ thread_call (struct thread *thread)
|
|||||||
realtime/1000, cputime/1000);
|
realtime/1000, cputime/1000);
|
||||||
}
|
}
|
||||||
#endif /* CONSUMED_TIME_CHECK */
|
#endif /* CONSUMED_TIME_CHECK */
|
||||||
|
|
||||||
XFREE (MTYPE_THREAD_FUNCNAME, thread->funcname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute thread */
|
/* Execute thread */
|
||||||
@ -1249,10 +1236,8 @@ funcname_thread_execute (struct thread_master *m,
|
|||||||
dummy.func = func;
|
dummy.func = func;
|
||||||
dummy.arg = arg;
|
dummy.arg = arg;
|
||||||
dummy.u.val = val;
|
dummy.u.val = val;
|
||||||
dummy.funcname = strip_funcname (funcname);
|
strip_funcname (dummy.funcname, funcname);
|
||||||
thread_call (&dummy);
|
thread_call (&dummy);
|
||||||
|
|
||||||
XFREE (MTYPE_THREAD_FUNCNAME, dummy.funcname);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ struct thread_master
|
|||||||
|
|
||||||
typedef unsigned char thread_type;
|
typedef unsigned char thread_type;
|
||||||
|
|
||||||
|
/* ISO C99 maximum function name length is 63 */
|
||||||
|
#define FUNCNAME_LEN 64
|
||||||
|
|
||||||
/* Thread itself. */
|
/* Thread itself. */
|
||||||
struct thread
|
struct thread
|
||||||
{
|
{
|
||||||
@ -79,13 +82,12 @@ struct thread
|
|||||||
} u;
|
} u;
|
||||||
struct timeval real;
|
struct timeval real;
|
||||||
struct cpu_thread_history *hist; /* cache pointer to cpu_history */
|
struct cpu_thread_history *hist; /* cache pointer to cpu_history */
|
||||||
char* funcname;
|
char funcname[FUNCNAME_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cpu_thread_history
|
struct cpu_thread_history
|
||||||
{
|
{
|
||||||
int (*func)(struct thread *);
|
int (*func)(struct thread *);
|
||||||
char *funcname;
|
|
||||||
unsigned int total_calls;
|
unsigned int total_calls;
|
||||||
struct time_stats
|
struct time_stats
|
||||||
{
|
{
|
||||||
@ -95,6 +97,7 @@ struct cpu_thread_history
|
|||||||
struct time_stats cpu;
|
struct time_stats cpu;
|
||||||
#endif
|
#endif
|
||||||
thread_type types;
|
thread_type types;
|
||||||
|
char funcname[FUNCNAME_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Clocks supported by Quagga */
|
/* Clocks supported by Quagga */
|
||||||
|
Loading…
Reference in New Issue
Block a user