Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1aa4faf49cdb1c81c633ad9b16a0d518590bdd27
[simgrid.git] / src / xbt / xbt_os_time.c
1 /* $Id$ */
2
3 /* sysdep.c -- all system dependency                                        */
4 /*  no system header should be loaded out of this file so that we have only */
5 /*  one file to check when porting to another OS                            */
6
7 /* Copyright (c) 2004-2007 The SimGrid team. All rights reserved.           */
8
9 /* This program is free software; you can redistribute it and/or modify it
10  * under the terms of the license (GNU LGPL) which comes with this package. */
11
12 #include "xbt/sysdep.h"
13 #include "xbt/xbt_os_time.h" /* this module */
14 #include "xbt/log.h"
15 #include "portable.h"
16 #include <math.h> /* floor */
17
18
19 #ifdef WIN32
20 #include <sys\timeb.h>
21 #endif
22
23 double xbt_os_time(void) {
24 #ifdef HAVE_GETTIMEOFDAY
25         struct timeval tv;
26         gettimeofday(&tv, NULL);
27 #elif defined(WIN32)
28         struct timeval tv;
29 #  if defined(WIN32_WCE) || (_WIN32_WINNT < 0x0400)
30         struct _timeb tm;
31
32         _ftime (&tm);
33
34         tv.tv_sec = tm.time;
35         tv.tv_usec = tm.millitm * 1000;
36
37 #  else
38         FILETIME  ft;
39         unsigned __int64 tm;
40
41         GetSystemTimeAsFileTime (&ft);
42         tm = (unsigned __int64)ft.dwHighDateTime << 32;
43         tm |= ft.dwLowDateTime;
44         tm /=10;
45         tm -= 11644473600000000ULL;
46
47         tv.tv_sec  = (long) (tm / 1000000L);
48         tv.tv_usec = (long) (tm % 1000000L);
49 #  endif /* windows version checker */
50
51 #else  /* not windows, no gettimeofday => poor resolution */
52 return (double)(time(NULL));
53 #endif /* HAVE_GETTIMEOFDAY? */
54
55 return (double)(tv.tv_sec + tv.tv_usec / 1000000.0);    
56 }
57
58 void xbt_os_sleep(double sec) {
59 #ifdef HAVE_USLEEP
60   sleep(sec);
61   (void)usleep( (sec - floor(sec)) * 1000000);
62
63 #elif _WIN32
64
65      Sleep((floor(sec) * 1000) +((sec - floor(sec)) * 1000));
66
67         
68 #else /* don't have usleep. Use select to sleep less than one second */
69   struct timeval timeout;
70
71   
72   timeout.tv_sec =  (unsigned long)(sec);
73   timeout.tv_usec = (sec - floor(sec)) * 1000000;
74               
75   select(0, NULL, NULL, NULL, &timeout);
76 #endif
77 }
78
79 /** @brief like free 
80     @hideinitializer */
81 XBT_PUBLIC(void) xbt_free_f(void* p)
82 {
83         free(p);
84 }
85
86
87 /* TSC (tick-level) timers are said to be unreliable on SMP hosts and thus 
88    disabled in SDL source code */ 
89
90
91 /* \defgroup XBT_sysdep All system dependency
92  * \brief This section describes many macros/functions that can serve as
93  *  an OS abstraction.
94  */
95
96 /*
97 double xbt_os_time(void) {
98 #ifdef HAVE_GETTIMEOFDAY
99   struct timeval tv;
100
101   gettimeofday(&tv, NULL);
102
103   return (double)(tv.tv_sec + tv.tv_usec / 1000000.0);
104 #else*/
105   /* Poor resolution */
106 /*  return (double)(time(NULL));*/
107 //#endif /* HAVE_GETTIMEOFDAY? */       
108 //}
109
110 /*XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sysdep, xbt, "System dependency");*/
111
112
113 struct s_xbt_os_timer {
114 #ifdef HAVE_GETTIMEOFDAY
115    struct timeval start,stop;
116 #else
117    unsigned long int start,stop;
118 #endif
119 };
120
121 xbt_os_timer_t xbt_os_timer_new(void) {
122    return xbt_new0(struct s_xbt_os_timer,1);
123 }
124 void xbt_os_timer_free(xbt_os_timer_t timer) {
125    free (timer);
126 }
127 void xbt_os_timer_start(xbt_os_timer_t timer) {
128 #ifdef HAVE_GETTIMEOFDAY
129   gettimeofday(&(timer->start), NULL);
130 #else 
131   timer->start = (unsigned long int)(time(NULL));
132 #endif
133 }
134 void xbt_os_timer_stop(xbt_os_timer_t timer) {
135 #ifdef HAVE_GETTIMEOFDAY
136   gettimeofday(&(timer->stop), NULL);
137 #else 
138   timer->stop = (unsigned long int)(time(NULL));
139 #endif
140 }
141 double xbt_os_timer_elapsed(xbt_os_timer_t timer) {
142 #ifdef HAVE_GETTIMEOFDAY
143    return  ((double)timer->stop.tv_sec)  - ((double)timer->start.tv_sec) +
144          ((((double)timer->stop.tv_usec) - ((double)timer->start.tv_usec)) / 1000000.0);
145 #else 
146    return  (double)timer->stop  - (double)timer->start;
147 #endif
148 }
149