Commit 8f00fd30 authored by Matthieu Dorier's avatar Matthieu Dorier

made timer list a member of the margo_instance structure

parent b6420b1a
...@@ -18,78 +18,47 @@ ...@@ -18,78 +18,47 @@
/* structure for mapping margo instance ids to corresponding timer instances */ /* structure for mapping margo instance ids to corresponding timer instances */
struct margo_timer_instance struct margo_timer_list
{ {
margo_instance_id mid;
ABT_mutex mutex; ABT_mutex mutex;
margo_timer_t *queue_head; margo_timer_t *queue_head;
}; };
#define MAX_TIMER_INSTANCES 8
static int timer_inst_table_size = 0;
static struct margo_timer_instance *timer_inst_table[MAX_TIMER_INSTANCES] = {NULL};
static struct margo_timer_instance *margo_get_timer_instance(
margo_instance_id mid);
static void margo_timer_queue( static void margo_timer_queue(
struct margo_timer_instance *timer_inst, struct margo_timer_list *timer_lst,
margo_timer_t *timer); margo_timer_t *timer);
int margo_timer_instance_init( struct margo_timer_list* margo_timer_list_create()
margo_instance_id mid)
{ {
struct margo_timer_instance *timer_inst; struct margo_timer_list *timer_lst;
if(timer_inst_table_size >= MAX_TIMER_INSTANCES)
return(-1);
timer_inst = malloc(sizeof(*timer_inst)); timer_lst = malloc(sizeof(*timer_lst));
if(!timer_inst) if(!timer_lst)
return(-1); return NULL;
timer_inst->mid = mid; ABT_mutex_create(&(timer_lst->mutex));
ABT_mutex_create(&(timer_inst->mutex)); timer_lst->queue_head = NULL;
timer_inst->queue_head = NULL;
/* add this instance to the table of active timer instances */ return timer_lst;
timer_inst_table[timer_inst_table_size++] = timer_inst;
return(0);
} }
void margo_timer_instance_finalize( void margo_timer_list_free(struct margo_timer_list* timer_lst)
margo_instance_id mid)
{ {
struct margo_timer_instance *timer_inst;
margo_timer_t *cur; margo_timer_t *cur;
int i = 0; int i = 0;
timer_inst = margo_get_timer_instance(mid); ABT_mutex_lock(timer_lst->mutex);
if(!timer_inst)
return;
ABT_mutex_lock(timer_inst->mutex);
/* delete any remaining timers from the queue */ /* delete any remaining timers from the queue */
while(timer_inst->queue_head) while(timer_lst->queue_head)
{ {
cur = timer_inst->queue_head; cur = timer_lst->queue_head;
DL_DELETE(timer_inst->queue_head, cur); DL_DELETE(timer_lst->queue_head, cur);
} }
ABT_mutex_unlock(timer_inst->mutex); ABT_mutex_unlock(timer_lst->mutex);
ABT_mutex_free(&(timer_inst->mutex)); ABT_mutex_free(&(timer_lst->mutex));
/* remove this timer instance from the active table */ free(timer_lst);
while(timer_inst_table[i] != timer_inst)
i++;
while(i < timer_inst_table_size - 1)
{
timer_inst_table[i] = timer_inst_table[i+1];
i++;
}
timer_inst_table[i] = NULL;
timer_inst_table_size--;
free(timer_inst);
return; return;
} }
...@@ -101,10 +70,10 @@ void margo_timer_init( ...@@ -101,10 +70,10 @@ void margo_timer_init(
void *cb_dat, void *cb_dat,
double timeout_ms) double timeout_ms)
{ {
struct margo_timer_instance *timer_inst; struct margo_timer_list *timer_lst;
timer_inst = margo_get_timer_instance(mid); timer_lst = margo_get_timer_list(mid);
assert(timer_inst); assert(timer_lst);
assert(timer); assert(timer);
memset(timer, 0, sizeof(*timer)); memset(timer, 0, sizeof(*timer));
...@@ -113,7 +82,7 @@ void margo_timer_init( ...@@ -113,7 +82,7 @@ void margo_timer_init(
timer->expiration = ABT_get_wtime() + (timeout_ms/1000); timer->expiration = ABT_get_wtime() + (timeout_ms/1000);
timer->prev = timer->next = NULL; timer->prev = timer->next = NULL;
margo_timer_queue(timer_inst, timer); margo_timer_queue(timer_lst, timer);
return; return;
} }
...@@ -122,16 +91,16 @@ void margo_timer_destroy( ...@@ -122,16 +91,16 @@ void margo_timer_destroy(
margo_instance_id mid, margo_instance_id mid,
margo_timer_t *timer) margo_timer_t *timer)
{ {
struct margo_timer_instance *timer_inst; struct margo_timer_list *timer_lst;
timer_inst = margo_get_timer_instance(mid); timer_lst = margo_get_timer_list(mid);
assert(timer_inst); assert(timer_lst);
assert(timer); assert(timer);
ABT_mutex_lock(timer_inst->mutex); ABT_mutex_lock(timer_lst->mutex);
if(timer->prev || timer->next) if(timer->prev || timer->next)
DL_DELETE(timer_inst->queue_head, timer); DL_DELETE(timer_lst->queue_head, timer);
ABT_mutex_unlock(timer_inst->mutex); ABT_mutex_unlock(timer_lst->mutex);
return; return;
} }
...@@ -141,22 +110,22 @@ void margo_check_timers( ...@@ -141,22 +110,22 @@ void margo_check_timers(
{ {
int ret; int ret;
margo_timer_t *cur; margo_timer_t *cur;
struct margo_timer_instance *timer_inst; struct margo_timer_list *timer_lst;
ABT_pool handler_pool; ABT_pool handler_pool;
double now = ABT_get_wtime(); double now = ABT_get_wtime();
timer_inst = margo_get_timer_instance(mid); timer_lst = margo_get_timer_list(mid);
assert(timer_inst); assert(timer_lst);
ABT_mutex_lock(timer_inst->mutex); ABT_mutex_lock(timer_lst->mutex);
/* iterate through timer list, performing timeout action /* iterate through timer list, performing timeout action
* for all elements which have passed expiration time * for all elements which have passed expiration time
*/ */
while(timer_inst->queue_head && (timer_inst->queue_head->expiration < now)) while(timer_lst->queue_head && (timer_lst->queue_head->expiration < now))
{ {
cur = timer_inst->queue_head; cur = timer_lst->queue_head;
DL_DELETE(timer_inst->queue_head, cur); DL_DELETE(timer_lst->queue_head, cur);
cur->prev = cur->next = NULL; cur->prev = cur->next = NULL;
/* schedule callback on the handler pool */ /* schedule callback on the handler pool */
...@@ -172,7 +141,7 @@ void margo_check_timers( ...@@ -172,7 +141,7 @@ void margo_check_timers(
cur->cb_fn(cur->cb_dat); cur->cb_fn(cur->cb_dat);
} }
} }
ABT_mutex_unlock(timer_inst->mutex); ABT_mutex_unlock(timer_lst->mutex);
return; return;
} }
...@@ -184,70 +153,47 @@ int margo_timer_get_next_expiration( ...@@ -184,70 +153,47 @@ int margo_timer_get_next_expiration(
margo_instance_id mid, margo_instance_id mid,
double *next_timer_exp) double *next_timer_exp)
{ {
struct margo_timer_instance *timer_inst; struct margo_timer_list *timer_lst;
double now = ABT_get_wtime(); double now = ABT_get_wtime();
int ret; int ret;
timer_inst = margo_get_timer_instance(mid); timer_lst = margo_get_timer_list(mid);
assert(timer_inst); assert(timer_lst);
ABT_mutex_lock(timer_inst->mutex); ABT_mutex_lock(timer_lst->mutex);
if(timer_inst->queue_head) if(timer_lst->queue_head)
{ {
*next_timer_exp = timer_inst->queue_head->expiration - now; *next_timer_exp = timer_lst->queue_head->expiration - now;
ret = 0; ret = 0;
} }
else else
{ {
ret = -1; ret = -1;
} }
ABT_mutex_unlock(timer_inst->mutex); ABT_mutex_unlock(timer_lst->mutex);
return(ret); return(ret);
} }
static struct margo_timer_instance *margo_get_timer_instance(
margo_instance_id mid)
{
struct margo_timer_instance *timer_inst = NULL;
int i = 0;
/* find the timer instance using the given margo id */
while(timer_inst_table[i] != NULL)
{
if(timer_inst_table[i]->mid == mid)
{
timer_inst = timer_inst_table[i];
break;
}
i++;
}
if(timer_inst)
assert(timer_inst->mutex != ABT_MUTEX_NULL);
return(timer_inst);
}
static void margo_timer_queue( static void margo_timer_queue(
struct margo_timer_instance *timer_inst, struct margo_timer_list *timer_lst,
margo_timer_t *timer) margo_timer_t *timer)
{ {
margo_timer_t *cur; margo_timer_t *cur;
ABT_mutex_lock(timer_inst->mutex); ABT_mutex_lock(timer_lst->mutex);
/* if list of timers is empty, put ourselves on it */ /* if list of timers is empty, put ourselves on it */
if(!(timer_inst->queue_head)) if(!(timer_lst->queue_head))
{ {
DL_APPEND(timer_inst->queue_head, timer); DL_APPEND(timer_lst->queue_head, timer);
} }
else else
{ {
/* something else already in queue, keep it sorted in ascending order /* something else already in queue, keep it sorted in ascending order
* of expiration time * of expiration time
*/ */
cur = timer_inst->queue_head; cur = timer_lst->queue_head;
do do
{ {
/* walk backwards through queue */ /* walk backwards through queue */
...@@ -257,18 +203,18 @@ static void margo_timer_queue( ...@@ -257,18 +203,18 @@ static void margo_timer_queue(
*/ */
if(cur->expiration < timer->expiration) if(cur->expiration < timer->expiration)
{ {
DL_APPEND_ELEM(timer_inst->queue_head, cur, timer); DL_APPEND_ELEM(timer_lst->queue_head, cur, timer);
break; break;
} }
}while(cur != timer_inst->queue_head); }while(cur != timer_lst->queue_head);
/* if we never found one with an expiration before this one, then /* if we never found one with an expiration before this one, then
* this one is the new head * this one is the new head
*/ */
if(timer->prev == NULL && timer->next == NULL) if(timer->prev == NULL && timer->next == NULL)
DL_PREPEND(timer_inst->queue_head, timer); DL_PREPEND(timer_lst->queue_head, timer);
} }
ABT_mutex_unlock(timer_inst->mutex); ABT_mutex_unlock(timer_lst->mutex);
return; return;
} }
...@@ -23,19 +23,16 @@ typedef struct margo_timed_element ...@@ -23,19 +23,16 @@ typedef struct margo_timed_element
} margo_timer_t; } margo_timer_t;
/** /**
* Initializes the margo timer interface * Creates a margo_timer_list.
* @param [in] mid Margo instance * @returns a new margo_timer_list, or NULL if failed
* @returns 0 on success, -1 on failure
*/ */
int margo_timer_instance_init( struct margo_timer_list* margo_timer_list_create();
margo_instance_id mid);
/** /**
* Shuts down the margo timer interface * Frees the timer list
* @param [in] mid Margo instance * @param [in] timer_lst timer list to free
*/ */
void margo_timer_instance_finalize( void margo_timer_list_free(struct margo_timer_list* timer_lst);
margo_instance_id mid);
/** /**
* Initializes a margo timer object which will perform some action * Initializes a margo timer object which will perform some action
...@@ -80,6 +77,12 @@ int margo_timer_get_next_expiration( ...@@ -80,6 +77,12 @@ int margo_timer_get_next_expiration(
margo_instance_id mid, margo_instance_id mid,
double *next_timer_exp); double *next_timer_exp);
/**
* Gets the margo_timer_list from the margo instance.
* This function is defined in margo.c.
*/
struct margo_timer_list *margo_get_timer_list(margo_instance_id mid);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -70,6 +70,8 @@ struct margo_finalize_cb ...@@ -70,6 +70,8 @@ struct margo_finalize_cb
struct margo_finalize_cb* next; struct margo_finalize_cb* next;
}; };
struct margo_timer_list; /* defined in margo-timer.c */
struct margo_instance struct margo_instance
{ {
/* mercury/argobots state */ /* mercury/argobots state */
...@@ -96,6 +98,9 @@ struct margo_instance ...@@ -96,6 +98,9 @@ struct margo_instance
ABT_cond finalize_cond; ABT_cond finalize_cond;
struct margo_finalize_cb* finalize_cb; struct margo_finalize_cb* finalize_cb;
/* timer data */
struct margo_timer_list* timer_list;
/* hash table to track multiplexed rpcs registered with margo */ /* hash table to track multiplexed rpcs registered with margo */
struct mplex_element *mplex_table; struct mplex_element *mplex_table;
...@@ -238,7 +243,7 @@ margo_instance_id margo_init(const char *addr_str, int mode, ...@@ -238,7 +243,7 @@ margo_instance_id margo_init(const char *addr_str, int mode,
err: err:
if(mid) if(mid)
{ {
margo_timer_instance_finalize(mid); margo_timer_list_free(mid->timer_list);
ABT_mutex_free(&mid->finalize_mutex); ABT_mutex_free(&mid->finalize_mutex);
ABT_cond_free(&mid->finalize_cond); ABT_cond_free(&mid->finalize_cond);
free(mid); free(mid);
...@@ -289,8 +294,8 @@ margo_instance_id margo_init_pool(ABT_pool progress_pool, ABT_pool handler_pool, ...@@ -289,8 +294,8 @@ margo_instance_id margo_init_pool(ABT_pool progress_pool, ABT_pool handler_pool,
mid->refcount = 1; mid->refcount = 1;
mid->finalize_cb = NULL; mid->finalize_cb = NULL;
ret = margo_timer_instance_init(mid); mid->timer_list = margo_timer_list_create();
if(ret != 0) goto err; if(mid->timer_list == NULL) goto err;
/* initialize the handle cache */ /* initialize the handle cache */
hret = margo_handle_cache_init(mid); hret = margo_handle_cache_init(mid);
...@@ -306,7 +311,7 @@ err: ...@@ -306,7 +311,7 @@ err:
if(mid) if(mid)
{ {
margo_handle_cache_destroy(mid); margo_handle_cache_destroy(mid);
margo_timer_instance_finalize(mid); margo_timer_list_free(mid->timer_list);
ABT_mutex_free(&mid->finalize_mutex); ABT_mutex_free(&mid->finalize_mutex);
ABT_cond_free(&mid->finalize_cond); ABT_cond_free(&mid->finalize_cond);
free(mid); free(mid);
...@@ -327,7 +332,7 @@ static void margo_cleanup(margo_instance_id mid) ...@@ -327,7 +332,7 @@ static void margo_cleanup(margo_instance_id mid)
free(tmp); free(tmp);
} }
margo_timer_instance_finalize(mid); margo_timer_list_free(mid->timer_list);
/* delete the hash used for multiplexing */ /* delete the hash used for multiplexing */
delete_multiplexing_hash(mid); delete_multiplexing_hash(mid);
...@@ -1442,3 +1447,8 @@ finish: ...@@ -1442,3 +1447,8 @@ finish:
ABT_mutex_unlock(mid->handle_cache_mtx); ABT_mutex_unlock(mid->handle_cache_mtx);
return hret; return hret;
} }
struct margo_timer_list *margo_get_timer_list(margo_instance_id mid)
{
return mid->timer_list;
}
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