#include "xbt/synchro.h"
#include "xbt/queue.h" /* this module */
-
+#include "gras/virtu.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_queue,xbt,"Message exchanging queue");
typedef struct s_xbt_queue_ {
* @seealso #xbt_queue_push
*/
void xbt_queue_push_timed(xbt_queue_t queue, const void *src,double delay) {
+ double timeout = xbt_os_time() + delay;
xbt_mutex_lock(queue->mutex);
if (queue->capacity != 0 && queue->capacity == xbt_dynar_length(queue->data)) {
DEBUG2("Capacity of %p exceded (=%d). Waiting",queue,queue->capacity);
xbt_cond_timedwait(queue->not_full,queue->mutex, delay);
+ /* check if a timeout occurs */
+ if (xbt_os_time() >= timeout) {
+ xbt_mutex_unlock(queue->mutex);
+ THROW0(timeout_error,0,"Timeout");
+ }
}
- /* check if a timeout occurs */
- if (queue->capacity != 0 && queue->capacity == xbt_dynar_length(queue->data)) {
- xbt_mutex_unlock(queue->mutex);
- THROW0(timeout_error,0,"Timeout");
- }
- else {
- xbt_dynar_push(queue->data,src);
- xbt_cond_signal(queue->not_empty);
- xbt_mutex_unlock(queue->mutex);
- }
+ xbt_dynar_push(queue->data,src);
+ xbt_cond_signal(queue->not_empty);
+ xbt_mutex_unlock(queue->mutex);
}
*
*/
void xbt_queue_pop_timed(xbt_queue_t queue, void* const dst,double delay) {
+ double timeout = xbt_os_time() + delay;
xbt_mutex_lock(queue->mutex);
if (xbt_dynar_length(queue->data) == 0) {
DEBUG1("Queue %p empty. Waiting",queue);
xbt_cond_timedwait(queue->not_empty,queue->mutex,delay);
+ /* check if a timeout occurs */
+ if (xbt_os_time() >= timeout) {
+ xbt_mutex_unlock(queue->mutex);
+ THROW0(timeout_error,0,"Timeout");
+ }
}
- /* check if a timeout occurs */
- if (xbt_dynar_length(queue->data) == 0) {
- xbt_mutex_unlock(queue->mutex);
- THROW0(timeout_error,0,"Timeout");
- }
- else {
- xbt_dynar_pop(queue->data,dst);
- xbt_cond_signal(queue->not_full);
- xbt_mutex_unlock(queue->mutex);
- }
+ 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.
* @seealso #xbt_queue_unshift
*/
void xbt_queue_unshift_timed(xbt_queue_t queue, const void *src,double delay) {
+ double timeout = xbt_os_time() + delay;
xbt_mutex_lock(queue->mutex);
if (queue->capacity != 0 && queue->capacity == xbt_dynar_length(queue->data)) {
DEBUG2("Capacity of %p exceded (=%d). Waiting",queue,queue->capacity);
xbt_cond_timedwait(queue->not_full,queue->mutex,delay);
+ /* check if a timeout occurs */
+ if (xbt_os_time() >= timeout) {
+ xbt_mutex_unlock(queue->mutex);
+ THROW0(timeout_error,0,"Timeout");
+ }
}
- /* check if a timeout occurs */
-
- if (queue->capacity != 0 && queue->capacity == xbt_dynar_length(queue->data)) {
-
- xbt_mutex_unlock(queue->mutex);
- THROW0(timeout_error,0,"Timeout");
- }
- else {
- xbt_dynar_unshift(queue->data,src);
- xbt_cond_signal(queue->not_empty);
- xbt_mutex_unlock(queue->mutex);
- }
+ xbt_dynar_unshift(queue->data,src);
+ xbt_cond_signal(queue->not_empty);
+ xbt_mutex_unlock(queue->mutex);
}
*
*/
void xbt_queue_shift_timed(xbt_queue_t queue, void* const dst,double delay) {
+ double timeout = xbt_os_time() + delay;
xbt_mutex_lock(queue->mutex);
- if (xbt_dynar_length(queue->data) == 0) {
+ while (xbt_dynar_length(queue->data) == 0) {
DEBUG1("Queue %p empty. Waiting",queue);
xbt_cond_timedwait(queue->not_empty,queue->mutex,delay);
+ /* check if a timeout occurs */
+ if (xbt_os_time() >= timeout) {
+ xbt_mutex_unlock(queue->mutex);
+ THROW0(timeout_error,0,"Timeout");
+ }
}
- /* check if a timeout occurs */
- if (xbt_dynar_length(queue->data) == 0) {
- xbt_mutex_unlock(queue->mutex);
- THROW0(timeout_error,0,"Timeout");
- }
- else {
- xbt_dynar_shift(queue->data,dst);
- xbt_cond_signal(queue->not_full);
- xbt_mutex_unlock(queue->mutex);
- }
+ xbt_dynar_shift(queue->data,dst);
+ xbt_cond_signal(queue->not_full);
+ xbt_mutex_unlock(queue->mutex);
}
--- /dev/null
+/* $Id$ */
+
+/* time - time related syscal wrappers */
+
+/* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <math.h> /* floor */
+
+#include "portable.h"
+
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+#include "gras/virtu.h"
+#include "xbt/xbt_os_time.h" /* private */
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(gras_virtu);
+double xbt_os_time(void) {
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ return (double)(tv.tv_sec + tv.tv_usec / 1000000.0);
+#else
+ /* Poor resolution */
+ return (double)(time(NULL));
+#endif /* HAVE_GETTIMEOFDAY? */
+}
+void xbt_os_sleep(double sec) {
+#ifdef HAVE_USLEEP
+ DEBUG1("Do sleep %f sec", sec);
+ sleep(sec);
+ (void)usleep( (sec - floor(sec)) * 1000000);
+
+#elif _WIN32
+ DEBUG1("Do sleep %f sec", sec);
+
+ Sleep((floor(sec) * 1000) +((sec - floor(sec)) * 1000));
+
+
+#else /* don't have usleep. Use select to sleep less than one second */
+ struct timeval timeout;
+
+ DEBUG1("Do sleep %f sec", sec);
+
+ timeout.tv_sec = (unsigned long)(sec);
+ timeout.tv_usec = (sec - floor(sec)) * 1000000;
+
+ select(0, NULL, NULL, NULL, &timeout);
+#endif
+}
--- /dev/null
+/* $Id$ */
+
+/* time - time related syscal wrappers */
+
+/* Copyright (c) 2003-2007 Martin Quinson. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "gras/Virtu/virtu_sg.h"
+
+/*
+ * Time elapsed since the begining of the simulation.
+ */
+double xbt_os_time() {
+ return SIMIX_get_clock();
+}
+
+/*
+ * Freeze the process for the specified amount of time
+ */
+void xbt_os_sleep(double sec) {
+ smx_action_t act_sleep;
+ smx_process_t proc = SIMIX_process_self();
+ smx_mutex_t mutex;
+ smx_cond_t cond;
+ /* create action to sleep */
+ act_sleep = SIMIX_action_sleep(SIMIX_process_get_host(proc),sec);
+
+ mutex = SIMIX_mutex_init();
+ SIMIX_mutex_lock(mutex);
+ /* create conditional and register action to it */
+ cond = SIMIX_cond_init();
+
+ SIMIX_register_condition_to_action(act_sleep, cond);
+ SIMIX_register_action_to_condition(act_sleep, cond);
+ SIMIX_cond_wait(cond,mutex);
+ SIMIX_mutex_unlock(mutex);
+
+ /* remove variables */
+ SIMIX_cond_destroy(cond);
+ SIMIX_mutex_destroy(mutex);
+ SIMIX_action_destroy(act_sleep);
+
+}