From 111463df0d9a94d78e136d3d81ff828ea96a2cac Mon Sep 17 00:00:00 2001 From: donassbr Date: Fri, 13 Jul 2007 14:20:20 +0000 Subject: [PATCH] Added xbt_os_time and xbt_os_sleep. Execute in the real and simulate systems. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3766 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- include/gras/virtu.h | 7 ++-- src/Makefile.am | 7 ++-- src/xbt/xbt_os_time.c | 9 ++--- src/xbt/xbt_queue.c | 82 ++++++++++++++++++++----------------------- src/xbt/xbt_rl_time.c | 54 ++++++++++++++++++++++++++++ src/xbt/xbt_sg_time.c | 45 ++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 55 deletions(-) create mode 100644 src/xbt/xbt_rl_time.c create mode 100644 src/xbt/xbt_sg_time.c diff --git a/include/gras/virtu.h b/include/gras/virtu.h index ff0b874033..837ede6ab6 100644 --- a/include/gras/virtu.h +++ b/include/gras/virtu.h @@ -11,6 +11,7 @@ #define GRAS_VIRTU_H #include "xbt/misc.h" /* SG_BEGIN_DECL */ +#include "xbt/time.h" SG_BEGIN_DECL() @@ -35,13 +36,11 @@ void gras_main(void); * @return number of second since the Epoch. * (00:00:00 UTC, January 1, 1970 in Real Life, and begining of simulation in SG) */ -XBT_PUBLIC(double) gras_os_time(void); - +#define gras_os_time() xbt_os_time() /** @brief sleeps for the given amount of time. * @param sec: number of seconds to sleep */ -XBT_PUBLIC(void) gras_os_sleep(double sec); - +#define gras_os_sleep(sec) xbt_os_sleep(sec) /** @brief get the fully-qualified name of the current host * * Returns the fully-qualified name of the host machine, or "localhost" if the name diff --git a/src/Makefile.am b/src/Makefile.am index cc48d3eea9..3f2bc94161 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -139,10 +139,11 @@ XBT_SRC=\ xbt/graphxml_parse.c XBT_RL_SRC = \ - xbt/xbt_rl_synchro.c - + xbt/xbt_rl_synchro.c \ + xbt/xbt_rl_time.c XBT_SG_SRC = \ - xbt/xbt_sg_synchro.c + xbt/xbt_sg_synchro.c \ + xbt/xbt_sg_time.c SURF_SRC= \ surf/maxmin.c \ diff --git a/src/xbt/xbt_os_time.c b/src/xbt/xbt_os_time.c index 94de59a99b..c74b4dd66f 100644 --- a/src/xbt/xbt_os_time.c +++ b/src/xbt/xbt_os_time.c @@ -32,6 +32,7 @@ XBT_PUBLIC(void) xbt_free_f(void* p) * an OS abstraction. */ +/* double xbt_os_time(void) { #ifdef HAVE_GETTIMEOFDAY struct timeval tv; @@ -39,11 +40,11 @@ double xbt_os_time(void) { gettimeofday(&tv, NULL); return (double)(tv.tv_sec + tv.tv_usec / 1000000.0); -#else +#else*/ /* Poor resolution */ - return (double)(time(NULL)); -#endif /* HAVE_GETTIMEOFDAY? */ -} +/* return (double)(time(NULL));*/ +//#endif /* HAVE_GETTIMEOFDAY? */ +//} /*XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sysdep, xbt, "System dependency");*/ diff --git a/src/xbt/xbt_queue.c b/src/xbt/xbt_queue.c index 50a3d300bd..0c45196a7b 100644 --- a/src/xbt/xbt_queue.c +++ b/src/xbt/xbt_queue.c @@ -16,7 +16,7 @@ #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_ { @@ -145,21 +145,20 @@ void xbt_queue_shift(xbt_queue_t queue, void* const dst) { * @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); } @@ -169,21 +168,20 @@ 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_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. @@ -191,23 +189,20 @@ void xbt_queue_pop_timed(xbt_queue_t queue, void* const dst,double delay) { * @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); } @@ -217,19 +212,18 @@ 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_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); } diff --git a/src/xbt/xbt_rl_time.c b/src/xbt/xbt_rl_time.c new file mode 100644 index 0000000000..f8f1c0566c --- /dev/null +++ b/src/xbt/xbt_rl_time.c @@ -0,0 +1,54 @@ +/* $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 /* 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 +} diff --git a/src/xbt/xbt_sg_time.c b/src/xbt/xbt_sg_time.c new file mode 100644 index 0000000000..b706ff12c0 --- /dev/null +++ b/src/xbt/xbt_sg_time.c @@ -0,0 +1,45 @@ +/* $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); + +} -- 2.20.1