From aed08a7a06b25674081adf610f369530e8c1e3bb Mon Sep 17 00:00:00 2001 From: mquinson Date: Thu, 19 Jul 2007 05:18:52 +0000 Subject: [PATCH 1/1] Fix delay semantic (hopefully) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3867 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/xbt/xbt_queue.c | 152 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 118 insertions(+), 34 deletions(-) diff --git a/src/xbt/xbt_queue.c b/src/xbt/xbt_queue.c index a31ac73fe3..a6f6278b13 100644 --- a/src/xbt/xbt_queue.c +++ b/src/xbt/xbt_queue.c @@ -145,15 +145,39 @@ void xbt_queue_shift(xbt_queue_t queue, void* const dst) { * @see #xbt_queue_push */ void xbt_queue_push_timed(xbt_queue_t queue, const void *src,double delay) { - double timeout = xbt_time() + delay; - xbt_mutex_lock(queue->mutex); - while ( (queue->capacity != 0) && (queue->capacity == xbt_dynar_length(queue->data)) && (xbt_time() < timeout) ) { - DEBUG2("Capacity of %p exceded (=%d). Waiting",queue,queue->capacity); - xbt_cond_timedwait(queue->not_full,queue->mutex, timeout - xbt_time()); - } - xbt_dynar_push(queue->data,src); - xbt_cond_signal(queue->not_empty); - xbt_mutex_unlock(queue->mutex); + double timeout = xbt_time() + delay; + xbt_ex_t e; + + xbt_mutex_lock(queue->mutex); + + if (delay == 0) { + if (queue->capacity != 0 && + queue->capacity == xbt_dynar_length(queue->data)) { + + xbt_mutex_unlock(queue->mutex); + THROW2(timeout_error,0,"Capacity of %p exceded (=%d), and delay = 0", + queue,queue->capacity); + } + } else { + while (queue->capacity != 0 && + queue->capacity == xbt_dynar_length(queue->data) && + (delay<0 || xbt_time() < timeout) ) { + + DEBUG2("Capacity of %p exceded (=%d). Waiting", + queue,queue->capacity); + TRY { + xbt_cond_timedwait(queue->not_full,queue->mutex, + delay < 0 ? -1 : timeout - xbt_time()); + } CATCH(e) { + xbt_mutex_unlock(queue->mutex); + RETHROW; + } + } + } + + xbt_dynar_push(queue->data,src); + xbt_cond_signal(queue->not_empty); + xbt_mutex_unlock(queue->mutex); } @@ -163,15 +187,33 @@ void xbt_queue_push_timed(xbt_queue_t queue, const void *src,double delay) { * */ void xbt_queue_pop_timed(xbt_queue_t queue, void* const dst,double delay) { - double timeout = xbt_time() + delay; - xbt_mutex_lock(queue->mutex); - while ( (xbt_dynar_length(queue->data) == 0) && (xbt_time() < timeout) ) { + double timeout = xbt_time() + delay; + xbt_ex_t e; + + xbt_mutex_lock(queue->mutex); + + if (delay == 0) { + if (xbt_dynar_length(queue->data) == 0) { + xbt_mutex_unlock(queue->mutex); + THROW0(timeout_error,0,"Delay = 0, and queue is empty"); + } + } else { + while ( (xbt_dynar_length(queue->data) == 0) && + (delay<0 || xbt_time() < timeout) ) { DEBUG1("Queue %p empty. Waiting",queue); - xbt_cond_timedwait(queue->not_empty,queue->mutex, timeout - xbt_time()); - } - xbt_dynar_pop(queue->data,dst); - xbt_cond_signal(queue->not_full); - xbt_mutex_unlock(queue->mutex); + TRY { + xbt_cond_timedwait(queue->not_empty,queue->mutex, + delay<0 ? -1 : timeout - xbt_time()); + } CATCH(e) { + xbt_mutex_unlock(queue->mutex); + RETHROW; + } + } + } + + xbt_dynar_pop(queue->data,dst); + xbt_cond_signal(queue->not_full); + xbt_mutex_unlock(queue->mutex); } /** @brief Unshift something to the message exchange queue, with a timeout. @@ -179,15 +221,39 @@ void xbt_queue_pop_timed(xbt_queue_t queue, void* const dst,double delay) { * @see #xbt_queue_unshift */ void xbt_queue_unshift_timed(xbt_queue_t queue, const void *src,double delay) { - double timeout = xbt_time() + delay; - xbt_mutex_lock(queue->mutex); - while ( (queue->capacity != 0) && (queue->capacity == xbt_dynar_length(queue->data)) && (xbt_time() < timeout) ) { - DEBUG2("Capacity of %p exceded (=%d). Waiting",queue,queue->capacity); - xbt_cond_timedwait(queue->not_full,queue->mutex, timeout - xbt_time()); - } - xbt_dynar_unshift(queue->data,src); - xbt_cond_signal(queue->not_empty); - xbt_mutex_unlock(queue->mutex); + double timeout = xbt_time() + delay; + xbt_ex_t e; + + xbt_mutex_lock(queue->mutex); + + if (delay==0) { + if (queue->capacity != 0 && + queue->capacity == xbt_dynar_length(queue->data)) { + + xbt_mutex_unlock(queue->mutex); + THROW2(timeout_error,0,"Capacity of %p exceded (=%d), and delay = 0", + queue,queue->capacity); + } + } else { + while (queue->capacity != 0 && + queue->capacity == xbt_dynar_length(queue->data) && + (delay<0 || xbt_time() < timeout) ) { + + DEBUG2("Capacity of %p exceded (=%d). Waiting", + queue,queue->capacity); + TRY { + xbt_cond_timedwait(queue->not_full,queue->mutex, + delay < 0 ? -1 : timeout - xbt_time()); + } CATCH(e) { + xbt_mutex_unlock(queue->mutex); + RETHROW; + } + } + } + + xbt_dynar_unshift(queue->data,src); + xbt_cond_signal(queue->not_empty); + xbt_mutex_unlock(queue->mutex); } @@ -197,13 +263,31 @@ void xbt_queue_unshift_timed(xbt_queue_t queue, const void *src,double delay) { * */ void xbt_queue_shift_timed(xbt_queue_t queue, void* const dst,double delay) { - double timeout = xbt_time() + delay; - xbt_mutex_lock(queue->mutex); - while ( (xbt_dynar_length(queue->data) == 0) && (xbt_time() < timeout) ) { + double timeout = xbt_time() + delay; + xbt_ex_t e; + + xbt_mutex_lock(queue->mutex); + + if (delay == 0) { + if (xbt_dynar_length(queue->data) == 0) { + xbt_mutex_unlock(queue->mutex); + THROW0(timeout_error,0,"Delay = 0, and queue is empty"); + } + } else { + while ( (xbt_dynar_length(queue->data) == 0) && + (delay<0 || xbt_time() < timeout) ) { DEBUG1("Queue %p empty. Waiting",queue); - xbt_cond_timedwait(queue->not_empty,queue->mutex, timeout - xbt_time()); - } - xbt_dynar_shift(queue->data,dst); - xbt_cond_signal(queue->not_full); - xbt_mutex_unlock(queue->mutex); + TRY { + xbt_cond_timedwait(queue->not_empty,queue->mutex, + delay<0 ? -1 : timeout - xbt_time()); + } CATCH(e) { + xbt_mutex_unlock(queue->mutex); + RETHROW; + } + } + } + + xbt_dynar_shift(queue->data,dst); + xbt_cond_signal(queue->not_full); + xbt_mutex_unlock(queue->mutex); } -- 2.20.1