Commit 3f3ad28f authored by Philip Carns's avatar Philip Carns

sort expiration queue

- also a new version of utlist.h with APPEND_ELEM macro
parent f3506aeb
......@@ -261,9 +261,12 @@ hg_return_t margo_forward_timed(
int ret;
hg_return_t* waited_hret;
struct timed_element el;
struct timed_element *cur;
/* calculate expiration time */
el.handle = handle;
el.prev = NULL;
el.next = NULL;
clock_gettime(clk_id, &el.expiration);
el.expiration.tv_sec += timeout_ms/1000;
el.expiration.tv_nsec += fmod(timeout_ms, 1000)*1000.0*1000.0;
......@@ -279,14 +282,41 @@ hg_return_t margo_forward_timed(
return(HG_NOMEM_ERROR);
}
/* TODO: split this out into a subroutine */
/* track timer */
/* TODO: sort properly */
/* TODO: timer_head->prev points to last element appended if we want to
* walk from the back and check the front for timeouts. Or we can do it
* the other way around.
*/
ABT_mutex_lock(mid->timer_mutex);
DL_APPEND(mid->timer_head, &el);
/* if queue of expiring ops is empty, put ourselves on it */
if(!mid->timer_head)
DL_APPEND(mid->timer_head, &el);
else
{
/* something else already in queue, keep it sorted in ascending order
* of expiration time
*/
cur = mid->timer_head;
do
{
/* walk backwards through queue */
cur = cur->prev;
/* as soon as we find an element that expires before this one,
* then we add ours after it
*/
if(cur->expiration.tv_sec < el.expiration.tv_sec ||
(cur->expiration.tv_sec == el.expiration.tv_sec &&
cur->expiration.tv_nsec < el.expiration.tv_nsec))
{
DL_APPEND_ELEM(mid->timer_head, cur, &el);
break;
}
}while(cur != mid->timer_head);
/* if we never found one with an expiration before this one, then
* this one is the new head
*/
if(el.prev == NULL && el.next == NULL)
DL_PREPEND(mid->timer_head, &el);
}
ABT_mutex_unlock(mid->timer_mutex);
hret = HG_Forward(handle, margo_cb, &eventual, in_struct);
......
......@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
/*
/*
* This file contains macros to manipulate singly and doubly-linked lists.
*
* 1. LL_ macros: singly-linked lists.
......@@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* To use singly-linked lists, your structure must have a "next" pointer.
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
* Either way, the pointer to the head of the list must be initialized to NULL.
*
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
......@@ -88,7 +88,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
#else
#else
#define _SV(elt,list)
#define _NEXT(elt,list,next) ((elt)->next)
#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to)
......@@ -193,11 +193,11 @@ do {
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
} else if (_ls_qsize == 0 || !_ls_q) { \
} else if ((_ls_qsize == 0) || (!_ls_q)) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
......@@ -445,7 +445,7 @@ do {
LL_FOREACH2(head,out,next) { \
if ((out)->field == (val)) break; \
} \
} while(0)
} while(0)
#define LL_SEARCH(head,out,elt,cmp) \
LL_SEARCH2(head,out,elt,cmp,next)
......@@ -455,9 +455,9 @@ do {
LL_FOREACH2(head,out,next) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
} while(0)
#define LL_REPLACE_ELEM(head, el, add) \
#define LL_REPLACE_ELEM2(head, el, add, next) \
do { \
LDECLTYPE(head) _tmp; \
assert(head != NULL); \
......@@ -477,26 +477,49 @@ do {
} \
} while (0)
#define LL_REPLACE_ELEM(head, el, add) \
LL_REPLACE_ELEM2(head, el, add, next)
#define LL_PREPEND_ELEM2(head, el, add, next) \
do { \
if((el)) { \
LDECLTYPE(head) _tmp; \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el); \
if ((head) == (el)) { \
(head) = (add); \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (el))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = (add); \
} \
} \
} else { \
LL_APPEND2(head, add, next); \
} \
} while (0) \
#define LL_PREPEND_ELEM(head, el, add) \
LL_PREPEND_ELEM2(head, el, add, next)
#define LL_APPEND_ELEM2(head, el, add, next) \
do { \
LDECLTYPE(head) _tmp; \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
if ((head) == (el)) { \
(head) = (add); \
if((el)) { \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el)->next; \
(el)->next = (add); \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (el))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = (add); \
} \
LL_PREPEND2(head, add, next); \
} \
} while (0) \
#define LL_APPEND_ELEM(head, el, add) \
LL_APPEND_ELEM2(head, el, add, next)
/******************************************************************************
* doubly linked list macros (non-circular) *
......@@ -531,7 +554,7 @@ do {
(head)->prev = (head); \
(head)->next = NULL; \
} \
} while (0)
} while (0)
#define DL_CONCAT(head1,head2) \
DL_CONCAT2(head1,head2,prev,next)
......@@ -549,7 +572,7 @@ do {
(head1)=(head2); \
} \
} \
} while (0)
} while (0)
#define DL_DELETE(head,del) \
DL_DELETE2(head,del,prev,next)
......@@ -570,7 +593,7 @@ do {
(head)->prev = (del)->prev; \
} \
} \
} while (0)
} while (0)
#define DL_COUNT(head,el,counter) \
DL_COUNT2(head,el,counter,next) \
......@@ -600,7 +623,7 @@ do {
#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2
#define DL_SEARCH2 LL_SEARCH2
#define DL_REPLACE_ELEM(head, el, add) \
#define DL_REPLACE_ELEM2(head, el, add, prev, next) \
do { \
assert(head != NULL); \
assert(el != NULL); \
......@@ -626,25 +649,71 @@ do {
} \
} while (0)
#define DL_REPLACE_ELEM(head, el, add) \
DL_REPLACE_ELEM2(head, el, add, prev, next)
#define DL_PREPEND_ELEM2(head, el, add, prev, next) \
do { \
if((el)) { \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
if ((head) == (el)) { \
(head) = (add); \
} else { \
(add)->prev->next = (add); \
} \
} else { \
DL_APPEND2(head, add, prev, next); \
} \
} while (0) \
#define DL_PREPEND_ELEM(head, el, add) \
DL_PREPEND_ELEM2(head, el, add, prev, next)
#define DL_APPEND_ELEM2(head, el, add, prev, next) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
if ((head) == (el)) { \
(head) = (add); \
if((el)) { \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el)->next; \
(add)->prev = (el); \
(el)->next = (add); \
if ((add)->next) { \
(add)->next->prev = (add); \
} else { \
(head)->prev = (add); \
} \
} else { \
(add)->prev->next = (add); \
DL_PREPEND2(head, add, prev, next); \
} \
} while (0) \
#define DL_APPEND_ELEM(head, el, add) \
DL_APPEND_ELEM2(head, el, add, prev, next)
/******************************************************************************
* circular doubly linked list macros *
*****************************************************************************/
#define CDL_APPEND(head,add) \
CDL_APPEND2(head,add,prev,next)
#define CDL_APPEND2(head,add,prev,next) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(add)->next = (head); \
(head)->prev = (add); \
(add)->prev->next = (add); \
} else { \
(add)->prev = (add); \
(add)->next = (add); \
(head) = (add); \
} \
} while (0)
#define CDL_PREPEND(head,add) \
CDL_PREPEND2(head,add,prev,next)
......@@ -659,7 +728,7 @@ do {
(add)->prev = (add); \
(add)->next = (add); \
} \
(head)=(add); \
(head) = (add); \
} while (0)
#define CDL_DELETE(head,del) \
......@@ -668,13 +737,13 @@ do {
#define CDL_DELETE2(head,del,prev,next) \
do { \
if ( ((head)==(del)) && ((head)->next == (head))) { \
(head) = 0L; \
(head) = NULL; \
} else { \
(del)->next->prev = (del)->prev; \
(del)->prev->next = (del)->next; \
if ((del) == (head)) (head)=(del)->next; \
} \
} while (0)
} while (0)
#define CDL_COUNT(head,el,counter) \
CDL_COUNT2(head,el,counter,next) \
......@@ -689,7 +758,7 @@ do {
CDL_FOREACH2(head,el,next)
#define CDL_FOREACH2(head,el,next) \
for(el=head;el;el=((el)->next==head ? 0L : (el)->next))
for(el=head;el;el=(((el)->next==head) ? 0L : (el)->next))
#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \
CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
......@@ -707,7 +776,7 @@ do {
CDL_FOREACH2(head,out,next) { \
if ((out)->field == (val)) break; \
} \
} while(0)
} while(0)
#define CDL_SEARCH(head,out,elt,cmp) \
CDL_SEARCH2(head,out,elt,cmp,next)
......@@ -717,9 +786,9 @@ do {
CDL_FOREACH2(head,out,next) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
} while(0)
#define CDL_REPLACE_ELEM(head, el, add) \
#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \
do { \
assert(head != NULL); \
assert(el != NULL); \
......@@ -739,19 +808,46 @@ do {
} \
} while (0)
#define CDL_REPLACE_ELEM(head, el, add) \
CDL_REPLACE_ELEM2(head, el, add, prev, next)
#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \
do { \
if((el)) \
{ \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
(add)->prev->next = (add); \
if ((head) == (el)) \
(head) = (add); \
} else { \
CDL_APPEND2(head, add, prev, next); \
} \
} while (0)
#define CDL_PREPEND_ELEM(head, el, add) \
CDL_PREPEND_ELEM2(head, el, add, prev, next)
#define CDL_APPEND_ELEM2(head, el, add, prev, next) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
(add)->prev->next = (add); \
if ((head) == (el)) { \
(head) = (add); \
if((el)) \
{ \
assert(head != NULL); \
assert(add != NULL); \
(add)->next = (el)->next; \
(add)->prev = (el); \
(el)->next = (add); \
(add)->next->prev = (add); \
} else { \
CDL_PREPEND2(head, add, prev, next); \
} \
} while (0) \
} while (0)
#define CDL_APPEND_ELEM(head, el, add) \
CDL_APPEND_ELEM2(head, el, add, prev, next)
#endif /* UTLIST_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