Triton Repository branch, master, updated. 7bf46352e0b63bb9b7ea0f03dabd8dd07dbd64f4
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Triton Repository". The branch, master has been updated via 7bf46352e0b63bb9b7ea0f03dabd8dd07dbd64f4 (commit) via 9c93bba0681d1542bb2bdbf3dac5df923b41f708 (commit) from 55c2957f48b2f46fe4ad9ddc6323a7d4a3383f58 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7bf46352e0b63bb9b7ea0f03dabd8dd07dbd64f4 Merge: 9c93bba0681d1542bb2bdbf3dac5df923b41f708 55c2957f48b2f46fe4ad9ddc6323a7d4a3383f58 Author: Kevin Harms <[email protected]> Date: Tue Aug 16 13:56:12 2011 -0500 Merge branch 'master' of git.mcs.anl.gov:triton commit 9c93bba0681d1542bb2bdbf3dac5df923b41f708 Author: Kevin Harms <[email protected]> Date: Wed Aug 3 22:25:59 2011 -0500 Change timer resource to only modify event loop from main libev thread. ----------------------------------------------------------------------- Summary of changes: code/src/common/resources/timer/timer.c | 82 +++++++++++++++++++++++++++--- 1 files changed, 73 insertions(+), 9 deletions(-) Diff of changes: diff --git a/code/src/common/resources/timer/timer.c b/code/src/common/resources/timer/timer.c index 76fc0d2..7ea7445 100644 --- a/code/src/common/resources/timer/timer.c +++ b/code/src/common/resources/timer/timer.c @@ -27,16 +27,21 @@ static int triton_timer_resource_id; static ev_timer timer_watcher; static struct ev_loop* timer_loop = NULL; static void timer_cb(EV_P_ ev_timer *w, int revents); +static int64_t global_timer_id_seed = 0; +static int64_t current_timer_id = 0; struct timer_op { struct timeval timer; + int milliseconds; + int64_t timer_id; ae_op_id_t op_id; struct ae_op op; triton_ret_t tret; }; static triton_mutex_t timer_mutex = TRITON_MUTEX_INITIALIZER; static ae_ops_t timer_oplist; +static ae_ops_t cancel_oplist; ae_define_post(triton_ret_t, triton_timer, int millisecs) { @@ -59,6 +64,7 @@ ae_define_post(triton_ret_t, triton_timer, int millisecs) top = ae_op_entry(op, struct timer_op, op); top->op_id = ae_id_gen(triton_timer_resource_id, (uintptr_t) op); top->tret = TRITON_SUCCESS; + top->milliseconds = millisecs; adjust.tv_sec = (int)(millisecs / 1e3); adjust.tv_usec = (millisecs % 1000) * 1e3; @@ -66,7 +72,8 @@ ae_define_post(triton_ret_t, triton_timer, int millisecs) timeradd(&adjust, &now, &(top->timer)); triton_mutex_lock(&timer_mutex); - //holder = ae_ops_peek(&timer_oplist); + top->timer_id = ++global_timer_id_seed; + holder = NULL; /* NOTE: we search the timer list from the back, on the assumption that * the newest timers added are most likely to be the furthest away from @@ -91,20 +98,69 @@ ae_define_post(triton_ret_t, triton_timer, int millisecs) ae_ops_enqueue(op, &timer_oplist); } + *__ae_op_id = top->op_id; + + triton_mutex_unlock(&timer_mutex); + + ae_resource_request_poll(op->ctx, triton_timer_resource_id); + + return TRITON_SUCCESS; +} + +static triton_ret_t triton_timer_poll(ae_context_t context) +{ + struct ae_op *op; + struct ae_op *op_head; + struct timer_op *top; + struct timer_op *top_head; + struct timeval result, now; + ev_tstamp seconds; + /* Did this end up at the head of the queue? */ - holder = ae_ops_peek(&timer_oplist); - if(holder == op) + triton_mutex_lock(&timer_mutex); + op_head = ae_ops_peek(&timer_oplist); + triton_mutex_unlock(&timer_mutex); + + /* + * Update the libev timer if there is a new deadline + */ + if ((op_head != NULL) && + (top_head = ae_op_entry(op_head, struct timer_op, op)) && + (top_head->timer_id != current_timer_id)) { - /* new head of queue; arm a new timer or modify the existing one */ + current_timer_id = top_head->timer_id; + + top = ae_op_entry(op_head, struct timer_op, op); + gettimeofday(&now, NULL); + timersub(&(top->timer), &now, &result); + seconds = (double)result.tv_sec + ((double)result.tv_usec / 1e6); + + /* timer has already expired, whoops. + * handle completing it in the libev callback. + */ + if (seconds < 0.0) + { + seconds = 0.0001; + } + if(timer_loop) ev_timer_stop(timer_loop, &timer_watcher); - ev_timer_set(&timer_watcher, (((ev_tstamp)millisecs)/1000.0), 0); - timer_loop = ae_resource_get_eloop(op->ctx); + ev_timer_set(&timer_watcher, seconds, 0); + timer_loop = ae_resource_get_eloop(op_head->ctx); ev_timer_start(timer_loop, &timer_watcher); } - *__ae_op_id = top->op_id; + /* harvest any timers that have been cancelled */ + triton_mutex_lock(&timer_mutex); + while((op = ae_ops_dequeue(&cancel_oplist))) + { + triton_mutex_unlock(&timer_mutex); + top = ae_op_entry(op, struct timer_op, op); + assert(top->tret == TRITON_ERR_CANCELED); + ae_opcache_complete_op(timer_opcache, op, triton_ret_t, top->tret); + triton_mutex_lock(&timer_mutex); + } triton_mutex_unlock(&timer_mutex); return TRITON_SUCCESS; @@ -147,10 +203,14 @@ static triton_ret_t triton_timer_cancel(ae_context_t triton_ctx, ae_op_id_t op_i assert(ae_ops_exists(&timer_oplist, &op->link)); ae_ops_del(op); - /* trigger callback immediately; no need to wait for a poll cycle */ + /* move to a special queue of cancelled timers */ ctx = op->ctx; + ae_ops_enqueue(op, &cancel_oplist); + triton_mutex_unlock(&timer_mutex); - ae_opcache_complete_op(timer_opcache, op, triton_ret_t, TRITON_ERR_CANCELED); + + /* request a poll for aesop to harvest the cancelled timer */ + ae_resource_request_poll(ctx, triton_timer_resource_id); return TRITON_SUCCESS; } @@ -158,6 +218,7 @@ static triton_ret_t triton_timer_cancel(ae_context_t triton_ctx, ae_op_id_t op_i struct ae_resource triton_timer_resource = { .resource_name = "timer", + .poll_context = triton_timer_poll, .cancel = triton_timer_cancel }; @@ -176,6 +237,7 @@ triton_ret_t triton_timer_init(void) ev_init(&timer_watcher, timer_cb); ae_ops_init(&timer_oplist); + ae_ops_init(&cancel_oplist); tret = AE_OPCACHE_INIT(struct timer_op, op, TIMER_DEFAULT_SIZE, &timer_opcache); if(tret != TRITON_SUCCESS) @@ -232,6 +294,8 @@ static void timer_cb(EV_P_ ev_timer *w, int revents) top = ae_op_entry(gop, struct timer_op, op); if(top) { + current_timer_id = top->timer_id; + gettimeofday(&now, NULL); timersub(&top->timer, &now, &diff); if(diff.tv_sec < 0 || diff.tv_usec < 0) hooks/post-receive -- Triton Repository
participants (1)
-
noreply@mcs.anl.gov