Commit fe328d06 authored by Rusty Russell's avatar Rusty Russell

timer: clean up hook allocator API

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 23e72d41
......@@ -3,17 +3,23 @@
#include <ccan/timer/timer.c>
#include <ccan/tap/tap.h>
static void *test_alloc(size_t len, void *arg)
struct timers_with_counters {
struct timers timers;
size_t num_alloc, num_free;
};
static void *test_alloc(struct timers *timers, size_t len)
{
(*(size_t *)arg)++;
((struct timers_with_counters *)timers)->num_alloc++;
return malloc(len);
}
static void test_free(const void *p, void *arg)
static void test_free(struct timers *timers, void *p)
{
if (p) {
(*(size_t *)arg)--;
free((void *)p);
((struct timers_with_counters *)timers)->num_free++;
free(p);
}
}
......@@ -25,37 +31,42 @@ static struct timemono timemono_from_nsec(unsigned long long nsec)
int main(void)
{
struct timers timers;
struct timers_with_counters tc;
struct timer t[64];
size_t num_allocs = 0;
const struct timemono epoch = { { 0, 0 } };
plan_tests(7);
tc.num_alloc = tc.num_free = 0;
plan_tests(12);
timers_set_allocator(test_alloc, test_free, &num_allocs);
timers_init(&timers, epoch);
timers_set_allocator(test_alloc, test_free);
timers_init(&tc.timers, epoch);
timer_init(&t[0]);
timer_addmono(&timers, &t[0],
timer_addmono(&tc.timers, &t[0],
timemono_from_nsec(TIMER_GRANULARITY << TIMER_LEVEL_BITS));
timers_expire(&timers, timemono_from_nsec(1));
ok1(num_allocs == 1);
timer_del(&timers, &t[0]);
ok1(num_allocs == 1);
timers_cleanup(&timers);
ok1(num_allocs == 0);
timers_expire(&tc.timers, timemono_from_nsec(1));
ok1(tc.num_alloc == 1);
ok1(tc.num_free == 0);
timer_del(&tc.timers, &t[0]);
ok1(tc.num_alloc == 1);
ok1(tc.num_free == 0);
timers_cleanup(&tc.timers);
ok1(tc.num_alloc == 1);
ok1(tc.num_free == 1);
/* Should restore defaults */
timers_set_allocator(NULL, NULL, NULL);
timers_set_allocator(NULL, NULL);
ok1(timer_alloc == timer_default_alloc);
ok1(timer_free == timer_default_free);
timers_init(&timers, epoch);
timer_addmono(&timers, &t[0],
timers_init(&tc.timers, epoch);
timer_addmono(&tc.timers, &t[0],
timemono_from_nsec(TIMER_GRANULARITY << TIMER_LEVEL_BITS));
ok1(num_allocs == 0);
timers_cleanup(&timers);
ok1(num_allocs == 0);
ok1(tc.num_alloc == 1);
ok1(tc.num_free == 1);
timers_cleanup(&tc.timers);
ok1(tc.num_alloc == 1);
ok1(tc.num_free == 1);
/* This exits depending on whether all tests passed */
return exit_status();
......
......@@ -11,23 +11,21 @@ struct timer_level {
struct list_head list[PER_LEVEL];
};
static void *timer_default_alloc(size_t len, void *arg)
static void *timer_default_alloc(struct timers *timers, size_t len)
{
return malloc(len);
}
static void timer_default_free(const void *p, void *arg)
static void timer_default_free(struct timers *timers, void *p)
{
free((void *)p);
free(p);
}
static void *(*timer_alloc)(size_t, void *) = timer_default_alloc;
static void (*timer_free)(const void *, void *) = timer_default_free;
static void *timer_arg;
static void *(*timer_alloc)(struct timers *, size_t) = timer_default_alloc;
static void (*timer_free)(struct timers *, void *) = timer_default_free;
void timers_set_allocator(void *(*alloc)(size_t len, void *arg),
void (*free)(const void *p, void *arg),
void *arg)
void timers_set_allocator(void *(*alloc)(struct timers *, size_t len),
void (*free)(struct timers *, void *p))
{
if (!alloc)
alloc = timer_default_alloc;
......@@ -35,7 +33,6 @@ void timers_set_allocator(void *(*alloc)(size_t len, void *arg),
free = timer_default_free;
timer_alloc = alloc;
timer_free = free;
timer_arg = arg;
}
static uint64_t time_to_grains(struct timemono t)
......@@ -166,7 +163,7 @@ static void add_level(struct timers *timers, unsigned int level)
unsigned int i;
struct list_head from_far;
l = timer_alloc(sizeof(*l), timer_arg);
l = timer_alloc(timers, sizeof(*l));
if (!l)
return;
......@@ -547,5 +544,5 @@ void timers_cleanup(struct timers *timers)
unsigned int l;
for (l = 0; l < ARRAY_SIZE(timers->level); l++)
timer_free(timers->level[l], timer_arg);
timer_free(timers, timers->level[l]);
}
......@@ -166,14 +166,12 @@ struct timers *timers_check(const struct timers *t, const char *abortstr);
* timers_set_allocator - set malloc/free functions.
* @alloc: allocator to use
* @free: unallocator to use (@p is NULL or a return from @alloc)
* @arg: argument to pass.
*
* This replaces the underlying malloc/free with these allocators.
* Setting either one to NULL restores the default allocators.
*/
void timers_set_allocator(void *(*alloc)(size_t len, void *arg),
void (*free)(const void *p, void *arg),
void *arg);
void timers_set_allocator(void *(*alloc)(struct timers *, size_t len),
void (*free)(struct timers *, void *p));
#ifdef CCAN_TIMER_DEBUG
#include <stdio.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment