1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
36
#include <sys/types.h>
37
#include <sys/times.h>
40
# include <sys/time.h>
42
# include <winsock2.h>
45
#include "sge_dstring.h"
47
#include "sge_unistd.h"
51
int gettimeofday(struct timeval *tz, struct timezone *tzp);
56
/* MT-NOTE: stopwatch profiling used in qmaster, qstat and qmon only */
57
/* MT-NOTE: stopwatch is phased out and will be replaced by libs/uti/sge_profiling */
58
static struct tms begin[NESTLEVEL];
59
static struct tms end[NESTLEVEL];
61
static time_t wtot[NESTLEVEL];
62
static time_t wbegin[NESTLEVEL];
63
static time_t wprev[NESTLEVEL];
64
static time_t wdiff[NESTLEVEL];
66
static int clock_tick;
67
static int time_log_interval[NESTLEVEL] = { -1, -1, -1, -1, -1 };
69
#ifdef TIMES_RETURNS_ZERO
70
static time_t inittime;
73
static void sge_stopwatch_stop(int i);
75
/* MT-NOTE: sge_stopwatch_stop() is not MT safe due to access to global variables */
76
static void sge_stopwatch_stop(int i)
80
if (i < 0 || i >= NESTLEVEL) {
83
if (time_log_interval[i] == -1) {
86
wend = times(&end[i]);
88
#ifdef TIMES_RETURNS_ZERO
89
/* times() returns 0 on these machines */
90
wend = (sge_get_gmt() - inittime) * clock_tick;
93
end[i].tms_utime = end[i].tms_utime - begin[i].tms_utime;
94
end[i].tms_stime = end[i].tms_stime - begin[i].tms_stime;
95
end[i].tms_cutime = end[i].tms_cutime - begin[i].tms_cutime;
96
end[i].tms_cstime = end[i].tms_cstime - begin[i].tms_cstime;
98
wtot[i] = wend - wbegin[i];
99
wdiff[i] = wend - wprev[i];
103
/****** uti/time/sge_get_gmt() ************************************************
105
* sge_get_gmt() -- Return current time
108
* u_long32 sge_get_gmt()
111
* Return current time
114
* MT-NOTE: sge_get_gmt() is MT safe (except for WIN32NATIVE)
117
* u_long32 - 32 bit time value
118
******************************************************************************/
119
u_long32 sge_get_gmt()
126
gettimeofday(&now, NULL);
132
gettimeofday(&now, &tzp);
136
return (u_long32)now.tv_sec;
139
struct tm *gmtimeval;
141
time(&long_time); /* Get time as long integer. */
143
/* MT-NOTE: gmtime() is not MT safe (WIN32NATIVE) */
144
gmtimeval = gmtime(&long_time); /* Convert to local time. */
145
long_time = mktime(gmtimeval);
150
/****** uti/time/append_time() **************************************************
152
* append_time() -- Convert time value into string
155
* const char* append_time(time_t i, dstring *buffer)
158
* Convert time value into string
161
* time_t i - time value
162
* dstring *buffer - dstring
163
* bool is_xml - write in XML dateTime format?
166
* const char* - time string (current time if 'i' was 0)
167
* dstring *buffer - buffer provided by caller
170
* MT-NOTE: append_time() is MT safe if localtime_r() can be used
172
* SHOULD BE REPLACED BY: sge_dstring_append_time()
174
******************************************************************************/
175
void append_time(time_t i, dstring *buffer, bool is_xml)
179
#ifdef HAS_LOCALTIME_R
182
tm = (struct tm *)localtime_r(&i, &tm_buffer);
188
sge_dstring_sprintf_append(buffer, "%04d-%02d-%02dT%02d:%02d:%02d",
189
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
190
tm->tm_hour, tm->tm_min, tm->tm_sec);
192
sge_dstring_sprintf_append(buffer, "%02d/%02d/%04d %02d:%02d:%02d",
193
tm->tm_mon + 1, tm->tm_mday, 1900 + tm->tm_year,
194
tm->tm_hour, tm->tm_min, tm->tm_sec);
198
/****** uti/time/sge_ctime() **************************************************
200
* sge_ctime() -- Convert time value into string
203
* const char* sge_ctime(time_t i, dstring *buffer)
206
* Convert time value into string
209
* time_t i - 0 or time value
212
* const char* - time string (current time if 'i' was 0)
213
* dstring *buffer - buffer provided by caller
216
* MT-NOTE: sge_at_time() is MT safe if localtime_r() can be used
219
* uti/time/sge_ctime32()
220
******************************************************************************/
221
const char *sge_ctime(time_t i, dstring *buffer)
223
#ifdef HAS_LOCALTIME_R
229
i = (time_t)sge_get_gmt();
230
#ifndef HAS_LOCALTIME_R
233
tm = (struct tm *)localtime_r(&i, &tm_buffer);
235
sge_dstring_sprintf(buffer, "%02d/%02d/%04d %02d:%02d:%02d",
236
tm->tm_mon + 1, tm->tm_mday, 1900 + tm->tm_year,
237
tm->tm_hour, tm->tm_min, tm->tm_sec);
239
return sge_dstring_get_string(buffer);
242
/* TODO: should be replaced by sge_dstring_append_time() */
243
const char *sge_ctimeXML(time_t i, dstring *buffer)
245
#ifdef HAS_LOCALTIME_R
251
i = (time_t)sge_get_gmt();
252
#ifndef HAS_LOCALTIME_R
255
tm = (struct tm *)localtime_r(&i, &tm_buffer);
257
sge_dstring_sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d",
258
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
259
tm->tm_hour, tm->tm_min, tm->tm_sec);
261
return sge_dstring_get_string(buffer);
265
/****** uti/time/sge_ctime32() ************************************************
267
* sge_ctime32() -- Convert time value into string (64 bit time_t)
270
* const char* sge_ctime32(u_long32 *i, dstring *buffer)
273
* Convert time value into string. This function is needed for
274
* systems with a 64 bit time_t because the ctime function would
275
* otherwise try to interpret the u_long32 value as
276
* a 64 bit value => $&&%$?$%!
279
* u_long32 *i - 0 or time value
280
* dstring *buffer - buffer provided by caller
283
* const char* - time string (current time if 'i' was 0)
286
* MT-NOTE: if ctime_r() is not available sge_ctime32() is not MT safe
289
* uti/time/sge_ctime()
290
******************************************************************************/
291
const char *sge_ctime32(u_long32 *i, dstring *buffer)
300
time_t temp = (time_t)*i;
303
/* if ctime_r() does not exist a mutex must be used to guard *all* ctime() calls */
304
s = ctime((time_t *)&temp);
306
s = (const char *)ctime_r((time_t *)&temp, str);
310
return sge_dstring_copy_string(buffer, s);
313
/****** uti/time/sge_at_time() ************************************************
315
* sge_at_time() -- ???
318
* const char* sge_at_time(time_t i, dstring *buffer)
324
* time_t i - 0 or time value
325
* dstring *buffer - buffer provided by caller
328
* const char* - time string (current time if 'i' was 0)
331
* MT-NOTE: sge_at_time() is MT safe if localtime_r() can be used
334
* uti/time/sge_ctime()
335
******************************************************************************/
336
const char *sge_at_time(time_t i, dstring *buffer)
338
#ifdef HAS_LOCALTIME_R
344
i = (time_t)sge_get_gmt();
345
#ifndef HAS_LOCALTIME_R
348
tm = (struct tm *)localtime_r(&i, &tm_buffer);
350
return sge_dstring_sprintf(buffer, "%04d%02d%02d%02d%02d.%02d",
351
tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday,
352
tm->tm_hour, tm->tm_min, tm->tm_sec);
355
/****** uti/time/sge_stopwatch_log() ******************************************
357
* sge_stopwatch_log() -- ???
360
* void sge_stopwatch_log(int i, const char *str)
367
* const char *str - ???
370
* MT-NOTE: sge_stopwatch_log() is not MT safe due to access to global variables
373
* uti/time/sge_stopwatch_start()
374
******************************************************************************/
375
void sge_stopwatch_log(int i, const char *str)
377
if (i < 0 || i >= NESTLEVEL) {
380
if (time_log_interval[i] == -1) {
384
sge_stopwatch_stop(i);
386
if ((wdiff[i] * 1000) / clock_tick >= time_log_interval[i]) {
387
static char SGE_FUNC[] = "";
389
WARNING((SGE_EVENT, "%-30s: %d/%d/%d", str,
390
(int) ((wtot[i] * 1000) / clock_tick),
391
(int) ((end[i].tms_utime * 1000) / clock_tick),
392
(int) ((end[i].tms_stime * 1000) / clock_tick)));
396
/****** uti/time/sge_stopwatch_start() ****************************************
398
* sge_stopwatch_start() -- ???
401
* void sge_stopwatch_start(int i)
410
* MT-NOTE: sge_stopwatch_start() is not MT safe due to access to global variables
413
* uti/time/sge_stopwatch_log()
414
******************************************************************************/
415
void sge_stopwatch_start(int i)
417
static int first = 1;
424
clock_tick = sysconf(_SC_CLK_TCK);
425
for (j = 0; j < NESTLEVEL; j++) {
426
wtot[j] = wbegin[j] = wprev[j] = wdiff[j] = 0;
427
sprintf(buf, "SGE_TIMELOG%d", j);
428
if ((cp = getenv(buf)) && (atoi(cp) >= 0)) {
429
time_log_interval[j] = atoi(cp);
431
time_log_interval[j] = -1;
437
if (i < 0 || i >= NESTLEVEL) {
440
if (time_log_interval[i] == -1) {
443
wbegin[i] = times(&begin[i]);
445
#ifdef TIMES_RETURNS_ZERO
446
/* times() return 0 on these machines */
447
wbegin[i] = (sge_get_gmt() - inittime) * clock_tick;
450
wprev[i] = wbegin[i];
453
/****** uti/time/duration_add_offset() ****************************************
455
* duration_add_offset() -- add function for time add
458
* u_long32 duration_add_offset(u_long32 duration, u_long32 offset)
461
* add function to catch ulong overflow. Returns max ulong value if necessary
464
* u_long32 duration - duration in seconds
465
* u_long32 offset - offset in seconds
468
* u_long32 - value < U_LONG32_MAX
471
* MT-NOTE: duration_add_offset() is not MT safe
472
*******************************************************************************/
473
u_long32 duration_add_offset(u_long32 duration, u_long32 offset)
475
if (duration == U_LONG32_MAX || offset == U_LONG32_MAX) {
479
if ((U_LONG32_MAX-offset) < duration) {
480
duration = U_LONG32_MAX;