1 /* ncbitime.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: ncbitime.c
27 *
28 * Author: Ostell, Kans
29 *
30 * Version Creation Date: 1/1/90
31 *
32 * $Revision: 6.3 $
33 *
34 * File Description:
35 * misc portable routines for
36 * dates, times, timers
37 *
38 * Modifications:
39 * --------------------------------------------------------------------------
40 * $Log: ncbitime.c,v $
41 * Revision 6.3 2006/10/19 16:58:26 lavr
42 * Cache clock rate instead of requesting it each time on OS_UNIX
43 *
44 * Revision 6.2 2001/01/19 20:26:12 kans
45 * support for OS_UNIX_DARWIN (contributed by William Van Etten)
46 *
47 * Revision 6.1 1997/10/29 02:45:09 vakatov
48 * Type castings to pass through the C++ compiler
49 *
50 * Revision 6.0 1997/08/25 18:17:21 madden
51 * Revision changed to 6.0
52 *
53 * Revision 5.7 1997/07/17 16:09:31 vakatov
54 * Encapsulated "NCBI_months" global variable into a {function + cpp macros}
55 *
56 * Revision 5.6 1996/12/03 21:48:33 vakatov
57 * Adopted for 32-bit MS-Windows DLLs
58 *
59 * Revision 5.5 1996/11/25 19:05:52 vakatov
60 * Made Nlm_GetDayTime() MT-safe
61 *
62 * Revision 5.3 1996/09/17 15:23:25 sad
63 * Corrected compilation problem under SunOS 4 related with CLK_TCK constant
64 *
65 * Revision 5.2 1996/09/16 20:19:57 kans
66 * structures cannot be empty, so needed to add #else condition in two places
67 *
68 * Revision 5.1 1996/09/16 19:37:19 sad
69 * Added set of functions for measuring CPU time.
70 * Added StopWatch set of functions.
71 *
72 * 04-15-93 Schuler Changed _cdecl to LIBCALL
73 *
74 * ==========================================================================
75 */
76
77 #include <ncbi.h>
78 #include <ncbithr.h>
79 #include <ncbiwin.h>
80
81 #ifdef OS_UNIX
82 #include <sys/times.h>
83 #include <unistd.h>
84 #endif
85
86 static char *STATIC__NCBI_months[12] = {
87 "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
x_NCBI_months(void)88 NLM_EXTERN char **x_NCBI_months(void) { return &STATIC__NCBI_months[0]; }
89
90 static char *ampm[2] = { "AM", "PM" };
91
92
93 /*****************************************************************************
94 *
95 * Nlm_GetSecs()
96 * returns computer time in seconds - for timing purposes only
97 *
98 *****************************************************************************/
Nlm_GetSecs(void)99 NLM_EXTERN time_t LIBCALL Nlm_GetSecs (void)
100 {
101 return time(NULL);
102 }
103
104 /*****************************************************************************
105 *
106 * Nlm_GetDayTime(DayTimePtr)
107 *
108 *****************************************************************************/
Nlm_GetDayTime(Nlm_DayTimePtr dtp)109 NLM_EXTERN Nlm_Boolean LIBCALL Nlm_GetDayTime (Nlm_DayTimePtr dtp)
110 {
111 #if (defined(SOLARIS_THREADS_AVAIL) || defined(POSIX_THREADS_AVAIL) || defined(WIN32)) && !defined(OS_UNIX_DARWIN)
112 time_t t = time( NULL );
113 #ifdef WIN32
114 static TNlmMutex localtime_lock;
115 if (NlmMutexLockEx( &localtime_lock ) != 0)
116 abort();
117 *dtp = *localtime( &t );
118 NlmMutexUnlock( localtime_lock );
119 #else
120 localtime_r(&t, dtp);
121 #endif
122 return TRUE;
123
124 #else
125 time_t ltime;
126 struct tm *dt;
127 Nlm_MemFill ((Nlm_VoidPtr) dtp, 0, sizeof(Nlm_DayTime));
128 time(<ime);
129 if ((dt = localtime (<ime)) != NULL)
130 {
131 Nlm_MemCopy ((Nlm_VoidPtr) dtp, (Nlm_VoidPtr) dt, sizeof (struct tm));
132 return TRUE;
133 }
134 return FALSE;
135 #endif
136 }
137
138 /*****************************************************************************
139 *
140 * Nlm_DayTimeStr(buf, date, time)
141 * fills buffer with formatted date and/or time
142 * date requires a 13 character buffer
143 * time requeres a 10 character buffer
144 * data and time takes 23
145 *
146 * eg. "Jan 28, 1988 12:59 PM"
147 *
148 *****************************************************************************/
Nlm_DayTimeStr(Nlm_CharPtr buf,Nlm_Boolean nlm_date,Nlm_Boolean nlm_time)149 NLM_EXTERN Nlm_Boolean LIBCALL Nlm_DayTimeStr (Nlm_CharPtr buf, Nlm_Boolean nlm_date, Nlm_Boolean nlm_time)
150
151 {
152 Nlm_DayTime dt;
153 char localbuf[30];
154 int pm;
155
156 buf[0] = '\0';
157
158 if ( ! Nlm_GetDayTime(&dt))
159 return FALSE;
160
161 if (nlm_date)
162 {
163 sprintf (localbuf, "%s %d, %d", NCBI_months [dt.tm_mon],
164 dt.tm_mday, dt.tm_year + 1900);
165 StringCpy (buf, localbuf);
166 }
167 if (nlm_time)
168 {
169 pm = 1;
170 if (dt.tm_hour == 0)
171 {
172 dt.tm_hour = 12;
173 pm = 0;
174 }
175 else if (dt.tm_hour < 12)
176 pm = 0;
177 else if (dt.tm_hour > 12)
178 dt.tm_hour -= 12;
179
180 sprintf (localbuf, "%3d:%2d %s", dt.tm_hour, dt.tm_min, ampm[pm]);
181 if (dt.tm_min < 10)
182 localbuf[4] = '0';
183 StringCat (buf, localbuf);
184 }
185 return TRUE;
186 }
187
188 struct _StopWatch {
189 #if defined(WIN32)
190 FILETIME start;
191 FILETIME stop;
192 #elif defined(OS_UNIX)
193 clock_t start;
194 clock_t stop;
195 clock_t rate;
196 #else
197 int dummy;
198 #endif
199 };
200 typedef struct _StopWatch Nlm_StopWatch;
201
Nlm_StopWatchNew(void)202 NLM_EXTERN Nlm_StopWatchPtr Nlm_StopWatchNew(void)
203 {
204 #if defined(WIN32) || defined(OS_UNIX)
205 Nlm_StopWatchPtr pSW = (Nlm_StopWatchPtr)Nlm_MemNew(sizeof(Nlm_StopWatch));
206 # if defined(OS_UNIX)
207 if (pSW != NULL)
208 pSW->rate = sysconf(_SC_CLK_TCK);
209 # endif
210 return pSW;
211 #else
212 ErrPostEx(SEV_WARNING, 0, 0,
213 "StopWatch is not implemented for this platform");
214 return NULL;
215 #endif
216 }
217
Nlm_StopWatchFree(Nlm_StopWatchPtr pStopWatch)218 NLM_EXTERN Nlm_StopWatchPtr Nlm_StopWatchFree(Nlm_StopWatchPtr pStopWatch)
219 {
220 #if defined(WIN32) || defined(OS_UNIX)
221 return (Nlm_StopWatchPtr) Nlm_MemFree(pStopWatch);
222 #else
223 ErrPostEx(SEV_WARNING, 0, 0,
224 "StopWatch is not implemented for this platform");
225 return NULL;
226 #endif
227 }
228
Nlm_StopWatchStart(Nlm_StopWatchPtr pSW)229 NLM_EXTERN Nlm_StopWatchPtr Nlm_StopWatchStart(Nlm_StopWatchPtr pSW)
230 {
231 #if defined(WIN32)
232 SYSTEMTIME systime;
233
234 GetSystemTime(&systime);
235 SystemTimeToFileTime(&systime, &pSW->start);
236 #elif defined(OS_UNIX)
237 struct tms foo;
238
239 pSW->start = times(&foo);
240 #else
241 ErrPostEx(SEV_WARNING, 0, 0,
242 "StopWatch is not implemented for this platform");
243 #endif
244 return pSW;
245 }
246
Nlm_StopWatchStop(Nlm_StopWatchPtr pSW)247 NLM_EXTERN Nlm_StopWatchPtr Nlm_StopWatchStop(Nlm_StopWatchPtr pSW)
248 {
249 #if defined(WIN32)
250 SYSTEMTIME systime;
251
252 GetSystemTime(&systime);
253 SystemTimeToFileTime(&systime, &pSW->stop);
254 #elif defined(OS_UNIX)
255 struct tms foo;
256
257 pSW->stop = times(&foo);
258 #else
259 ErrPostEx(SEV_WARNING, 0, 0,
260 "StopWatch is not implemented for this platform");
261 #endif
262 return pSW;
263 }
264
Nlm_GetElapsedTime(Nlm_StopWatchPtr pSW)265 NLM_EXTERN Nlm_FloatHi Nlm_GetElapsedTime(Nlm_StopWatchPtr pSW)
266 {
267 Nlm_FloatHi res = 0;
268 #if defined(WIN32)
269 FILETIME ft;
270
271 if (pSW->start.dwLowDateTime > pSW->stop.dwLowDateTime) {
272 ft.dwLowDateTime = (0xFFFFFFFFL - pSW->start.dwLowDateTime) + 1
273 + pSW->stop.dwLowDateTime;
274 ft.dwHighDateTime =
275 pSW->stop.dwHighDateTime - pSW->start.dwHighDateTime - 1;
276 } else {
277 ft.dwLowDateTime =
278 pSW->stop.dwLowDateTime - pSW->start.dwLowDateTime;
279 ft.dwHighDateTime =
280 pSW->stop.dwHighDateTime - pSW->start.dwHighDateTime;
281 }
282
283 return res = (Nlm_FloatHi)ft.dwHighDateTime/5000000L*0x80000000L +
284 (Nlm_FloatHi)ft.dwLowDateTime/10000000L;
285 #elif defined(OS_UNIX)
286 res = ((Nlm_FloatHi)pSW->stop - pSW->start) / pSW->rate;
287 #else
288 ErrPostEx(SEV_WARNING, 0, 0,
289 "StopWatch is not implemented for this platform");
290 #endif
291
292 return res;
293 }
294
295
296 struct _CPUTime {
297 #if defined(WIN32)
298 FILETIME crtime;
299 FILETIME extime;
300 FILETIME systime;
301 FILETIME usrtime;
302 #elif defined(OS_UNIX)
303 struct tms times;
304 clock_t rate;
305 #else
306 int dummy;
307 #endif
308 };
309
310 typedef struct _CPUTime Nlm_CPUTime;
311
Nlm_CPUTimeMeasure(void)312 NLM_EXTERN Nlm_CPUTimePtr Nlm_CPUTimeMeasure(void)
313 {
314 #if defined(WIN32) || defined(OS_UNIX)
315 Nlm_CPUTimePtr pTime = (Nlm_CPUTimePtr) Nlm_MemNew(sizeof(Nlm_CPUTime));
316 if (pTime != NULL) {
317 #endif
318
319 #if defined(WIN32)
320 GetProcessTimes(GetCurrentProcess(),
321 &pTime->crtime,
322 &pTime->extime,
323 &pTime->systime,
324 &pTime->usrtime
325 );
326 #elif defined(OS_UNIX)
327 times(&pTime->times);
328 pTime->rate = sysconf(_SC_CLK_TCK);
329 #else
330 ErrPostEx(SEV_WARNING, 0, 0,
331 "CPU time measuring is not implemented for this platform");
332 return NULL;
333 #endif
334
335 #if defined(WIN32) || defined(OS_UNIX)
336 }
337
338 return pTime;
339 #endif
340 }
341
Nlm_CPUTimeFree(Nlm_CPUTimePtr pTime)342 NLM_EXTERN Nlm_CPUTimePtr Nlm_CPUTimeFree(Nlm_CPUTimePtr pTime)
343 {
344 #if defined(WIN32) || defined(OS_UNIX)
345 return (Nlm_CPUTimePtr) Nlm_MemFree(pTime);
346 #else
347 ErrPostEx(SEV_WARNING, 0, 0,
348 "CPU time measuring is not implemented for this platform");
349 return NULL;
350 #endif
351 }
352
Nlm_CPUTimeGetSys(Nlm_CPUTimePtr pTime)353 NLM_EXTERN Nlm_FloatHi Nlm_CPUTimeGetSys(Nlm_CPUTimePtr pTime)
354 {
355 #if defined(WIN32)
356 return (Nlm_FloatHi)pTime->systime.dwHighDateTime * 0x80000000L/5000000L
357 + (Nlm_FloatHi)pTime->systime.dwLowDateTime / 10000000L;
358 #elif defined(OS_UNIX)
359 return (Nlm_FloatHi)pTime->times.tms_stime / pTime->rate;
360 #else
361 ErrPostEx(SEV_WARNING, 0, 0,
362 "CPU time measuring is not implemented for this platform");
363 return 0;
364 #endif
365 }
366
Nlm_CPUTimeGetUser(Nlm_CPUTimePtr pTime)367 NLM_EXTERN Nlm_FloatHi Nlm_CPUTimeGetUser(Nlm_CPUTimePtr pTime)
368 {
369 #if defined(WIN32)
370 return (Nlm_FloatHi)pTime->usrtime.dwHighDateTime * 0x80000000L/5000000L
371 + (Nlm_FloatHi)pTime->usrtime.dwLowDateTime / 10000000L;
372 #elif defined(OS_UNIX)
373 return (Nlm_FloatHi)pTime->times.tms_utime / pTime->rate;
374 #else
375 ErrPostEx(SEV_WARNING, 0, 0,
376 "CPU time measuring is not implemented for this platform");
377 return 0;
378 #endif
379 }
380
381