~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/uti/sge_time.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
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
 
16
 * 
 
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.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
 
 
33
#include <stdlib.h>
 
34
#include <stdio.h>
 
35
#include <time.h>
 
36
#include <sys/types.h>
 
37
#include <sys/times.h> 
 
38
 
 
39
#ifndef WIN32NATIVE
 
40
#       include <sys/time.h>
 
41
#else 
 
42
#       include <winsock2.h>
 
43
#endif 
 
44
 
 
45
#include "sge_dstring.h"
 
46
#include "sge_time.h"
 
47
#include "sge_unistd.h"
 
48
#include "sge_log.h"
 
49
 
 
50
#ifdef WIN32
 
51
int gettimeofday(struct timeval *tz, struct timezone *tzp);
 
52
#endif
 
53
 
 
54
#define NESTLEVEL 5
 
55
 
 
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];
 
60
 
 
61
static time_t wtot[NESTLEVEL];
 
62
static time_t wbegin[NESTLEVEL];
 
63
static time_t wprev[NESTLEVEL];
 
64
static time_t wdiff[NESTLEVEL];
 
65
 
 
66
static int clock_tick;
 
67
static int time_log_interval[NESTLEVEL] = { -1, -1, -1, -1, -1 };
 
68
 
 
69
#ifdef TIMES_RETURNS_ZERO
 
70
static time_t inittime;
 
71
#endif
 
72
 
 
73
static void sge_stopwatch_stop(int i);  
 
74
 
 
75
/* MT-NOTE: sge_stopwatch_stop() is not MT safe due to access to global variables */
 
76
static void sge_stopwatch_stop(int i)
 
77
{
 
78
   time_t wend;
 
79
 
 
80
   if (i < 0 || i >= NESTLEVEL) {
 
81
      return;
 
82
   }
 
83
   if (time_log_interval[i] == -1) {
 
84
      return;
 
85
   }
 
86
   wend = times(&end[i]);
 
87
 
 
88
#ifdef TIMES_RETURNS_ZERO
 
89
   /* times() returns 0 on these machines */
 
90
   wend = (sge_get_gmt() - inittime) * clock_tick;
 
91
#endif
 
92
 
 
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;
 
97
 
 
98
   wtot[i]  = wend - wbegin[i];
 
99
   wdiff[i] = wend - wprev[i];
 
100
   wprev[i] = wend;
 
101
}
 
102
 
 
103
/****** uti/time/sge_get_gmt() ************************************************
 
104
*  NAME
 
105
*     sge_get_gmt() -- Return current time 
 
106
*
 
107
*  SYNOPSIS
 
108
*     u_long32 sge_get_gmt() 
 
109
*
 
110
*  FUNCTION
 
111
*     Return current time 
 
112
*
 
113
*  NOTES
 
114
*     MT-NOTE: sge_get_gmt() is MT safe (except for WIN32NATIVE)
 
115
*
 
116
*  RESULT
 
117
*     u_long32 - 32 bit time value
 
118
******************************************************************************/
 
119
u_long32 sge_get_gmt()
 
120
{
 
121
#ifndef WIN32NATIVE
 
122
 
 
123
   struct timeval now;
 
124
 
 
125
#  ifdef SOLARIS
 
126
   gettimeofday(&now, NULL);
 
127
#  else
 
128
#     ifdef SINIX
 
129
   gettimeofday(&now);
 
130
#     else
 
131
   struct timezone tzp;
 
132
   gettimeofday(&now, &tzp);
 
133
#     endif
 
134
#  endif
 
135
 
 
136
   return (u_long32)now.tv_sec;
 
137
#else
 
138
   time_t long_time;
 
139
   struct tm *gmtimeval;
 
140
 
 
141
        time(&long_time);                  /* Get time as long integer. */
 
142
 
 
143
   /* MT-NOTE: gmtime() is not MT safe (WIN32NATIVE) */
 
144
        gmtimeval = gmtime(&long_time);    /* Convert to local time. */
 
145
        long_time = mktime(gmtimeval);
 
146
        return long_time;
 
147
#endif
 
148
}
 
149
 
 
150
/****** uti/time/append_time() **************************************************
 
151
*  NAME
 
152
*     append_time() -- Convert time value into string 
 
153
*
 
154
*  SYNOPSIS
 
155
*     const char* append_time(time_t i, dstring *buffer) 
 
156
*
 
157
*  FUNCTION
 
158
*     Convert time value into string 
 
159
*
 
160
*  INPUTS
 
161
*     time_t i - time value 
 
162
*     dstring *buffer - dstring
 
163
*     bool is_xml - write in XML dateTime format?
 
164
*
 
165
*  RESULT
 
166
*     const char* - time string (current time if 'i' was 0) 
 
167
*     dstring *buffer - buffer provided by caller
 
168
*
 
169
*  NOTES
 
170
*     MT-NOTE: append_time() is MT safe if localtime_r() can be used
 
171
*
 
172
*     SHOULD BE REPLACED BY: sge_dstring_append_time()
 
173
*
 
174
******************************************************************************/
 
175
void append_time(time_t i, dstring *buffer, bool is_xml) 
 
176
{
 
177
   struct tm *tm;
 
178
 
 
179
#ifdef HAS_LOCALTIME_R
 
180
   struct tm tm_buffer;
 
181
   
 
182
   tm = (struct tm *)localtime_r(&i, &tm_buffer);
 
183
#else   
 
184
   tm = localtime(&i);
 
185
#endif
 
186
 
 
187
   if (is_xml) {
 
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);
 
191
   } else {
 
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);
 
195
   }
 
196
}
 
197
 
 
198
/****** uti/time/sge_ctime() **************************************************
 
199
*  NAME
 
200
*     sge_ctime() -- Convert time value into string 
 
201
*
 
202
*  SYNOPSIS
 
203
*     const char* sge_ctime(time_t i, dstring *buffer) 
 
204
*
 
205
*  FUNCTION
 
206
*     Convert time value into string 
 
207
*
 
208
*  INPUTS
 
209
*     time_t i - 0 or time value 
 
210
*
 
211
*  RESULT
 
212
*     const char* - time string (current time if 'i' was 0) 
 
213
*     dstring *buffer - buffer provided by caller
 
214
*
 
215
*  NOTES
 
216
*     MT-NOTE: sge_at_time() is MT safe if localtime_r() can be used
 
217
*
 
218
*  SEE ALSO
 
219
*     uti/time/sge_ctime32()
 
220
******************************************************************************/
 
221
const char *sge_ctime(time_t i, dstring *buffer) 
 
222
{
 
223
#ifdef HAS_LOCALTIME_R
 
224
   struct tm tm_buffer;
 
225
#endif
 
226
   struct tm *tm;
 
227
 
 
228
   if (!i)
 
229
      i = (time_t)sge_get_gmt();
 
230
#ifndef HAS_LOCALTIME_R
 
231
   tm = localtime(&i);
 
232
#else
 
233
   tm = (struct tm *)localtime_r(&i, &tm_buffer);
 
234
#endif
 
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);
 
238
 
 
239
   return sge_dstring_get_string(buffer);
 
240
}
 
241
 
 
242
/* TODO: should be replaced by sge_dstring_append_time() */
 
243
const char *sge_ctimeXML(time_t i, dstring *buffer) 
 
244
{
 
245
#ifdef HAS_LOCALTIME_R
 
246
   struct tm tm_buffer;
 
247
#endif
 
248
   struct tm *tm;
 
249
 
 
250
   if (!i)
 
251
      i = (time_t)sge_get_gmt();
 
252
#ifndef HAS_LOCALTIME_R
 
253
   tm = localtime(&i);
 
254
#else
 
255
   tm = (struct tm *)localtime_r(&i, &tm_buffer);
 
256
#endif
 
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);
 
260
 
 
261
   return sge_dstring_get_string(buffer);
 
262
}
 
263
 
 
264
 
 
265
/****** uti/time/sge_ctime32() ************************************************
 
266
*  NAME
 
267
*     sge_ctime32() -- Convert time value into string (64 bit time_t) 
 
268
*
 
269
*  SYNOPSIS
 
270
*     const char* sge_ctime32(u_long32 *i, dstring *buffer) 
 
271
*
 
272
*  FUNCTION
 
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 => $&&%$?$%!
 
277
*
 
278
*  INPUTS
 
279
*     u_long32 *i - 0 or time value 
 
280
*     dstring *buffer - buffer provided by caller
 
281
*
 
282
*  RESULT
 
283
*     const char* - time string (current time if 'i' was 0)
 
284
 
285
*  NOTE
 
286
*     MT-NOTE: if ctime_r() is not available sge_ctime32() is not MT safe
 
287
*
 
288
*  SEE ALSO
 
289
*     uti/time/sge_ctime()
 
290
******************************************************************************/
 
291
const char *sge_ctime32(u_long32 *i, dstring *buffer) 
 
292
{
 
293
   const char *s;
 
294
#ifdef HAS_CTIME_R
 
295
   char str[128]; 
 
296
#endif
 
297
#if SOLARIS64
 
298
   volatile
 
299
#endif
 
300
   time_t temp = (time_t)*i;
 
301
 
 
302
#ifndef HAS_CTIME_R
 
303
   /* if ctime_r() does not exist a mutex must be used to guard *all* ctime() calls */
 
304
   s = ctime((time_t *)&temp);
 
305
#else 
 
306
   s = (const char *)ctime_r((time_t *)&temp, str);
 
307
#endif
 
308
   if (!s)
 
309
      return NULL;
 
310
   return sge_dstring_copy_string(buffer, s);
 
311
}
 
312
 
 
313
/****** uti/time/sge_at_time() ************************************************
 
314
*  NAME
 
315
*     sge_at_time() -- ??? 
 
316
*
 
317
*  SYNOPSIS
 
318
*     const char* sge_at_time(time_t i, dstring *buffer) 
 
319
*
 
320
*  FUNCTION
 
321
*     ??? 
 
322
*
 
323
*  INPUTS
 
324
*     time_t i - 0 or time value 
 
325
*     dstring *buffer - buffer provided by caller
 
326
*
 
327
*  RESULT
 
328
*     const char* - time string (current time if 'i' was 0) 
 
329
*
 
330
*  NOTES
 
331
*     MT-NOTE: sge_at_time() is MT safe if localtime_r() can be used
 
332
*
 
333
*  SEE ALSO
 
334
*     uti/time/sge_ctime() 
 
335
******************************************************************************/
 
336
const char *sge_at_time(time_t i, dstring *buffer) 
 
337
{
 
338
#ifdef HAS_LOCALTIME_R
 
339
   struct tm tm_buffer;
 
340
#endif
 
341
   struct tm *tm;
 
342
 
 
343
   if (!i)
 
344
      i = (time_t)sge_get_gmt();
 
345
#ifndef HAS_LOCALTIME_R
 
346
   tm = localtime(&i);
 
347
#else
 
348
   tm = (struct tm *)localtime_r(&i, &tm_buffer);
 
349
#endif
 
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);
 
353
}
 
354
 
 
355
/****** uti/time/sge_stopwatch_log() ******************************************
 
356
*  NAME
 
357
*     sge_stopwatch_log() -- ??? 
 
358
*
 
359
*  SYNOPSIS
 
360
*     void sge_stopwatch_log(int i, const char *str) 
 
361
*
 
362
*  FUNCTION
 
363
*     ??? 
 
364
*
 
365
*  INPUTS
 
366
*     int i           - ??? 
 
367
*     const char *str - ??? 
 
368
*
 
369
*  NOTES
 
370
*     MT-NOTE: sge_stopwatch_log() is not MT safe due to access to global variables
 
371
*
 
372
*  SEE ALSO
 
373
*     uti/time/sge_stopwatch_start() 
 
374
******************************************************************************/
 
375
void sge_stopwatch_log(int i, const char *str)
 
376
{
 
377
   if (i < 0 || i >= NESTLEVEL) {
 
378
      return;
 
379
   }
 
380
   if (time_log_interval[i] == -1) {
 
381
      return;
 
382
   }
 
383
 
 
384
   sge_stopwatch_stop(i);
 
385
 
 
386
   if ((wdiff[i] * 1000) / clock_tick >= time_log_interval[i]) {
 
387
      static char SGE_FUNC[] = "";
 
388
 
 
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)));
 
393
   }
 
394
}          
 
395
 
 
396
/****** uti/time/sge_stopwatch_start() ****************************************
 
397
*  NAME
 
398
*     sge_stopwatch_start() -- ??? 
 
399
*
 
400
*  SYNOPSIS
 
401
*     void sge_stopwatch_start(int i) 
 
402
*
 
403
*  FUNCTION
 
404
*     ??? 
 
405
*
 
406
*  INPUTS
 
407
*     int i - ??? 
 
408
*
 
409
*  NOTES
 
410
*     MT-NOTE: sge_stopwatch_start() is not MT safe due to access to global variables
 
411
*
 
412
*  SEE ALSO
 
413
*     uti/time/sge_stopwatch_log() 
 
414
******************************************************************************/
 
415
void sge_stopwatch_start(int i)
 
416
{
 
417
   static int first = 1;
 
418
   int j;
 
419
   char *cp;
 
420
 
 
421
   if (first) {
 
422
      char buf[24];
 
423
 
 
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);
 
430
         } else {
 
431
            time_log_interval[j] = -1;
 
432
         }
 
433
      }
 
434
      first = 0;
 
435
   }
 
436
 
 
437
   if (i < 0 || i >= NESTLEVEL) {
 
438
      return;
 
439
   }
 
440
   if (time_log_interval[i] == -1) {
 
441
      return;
 
442
   }
 
443
   wbegin[i] = times(&begin[i]);
 
444
 
 
445
#ifdef TIMES_RETURNS_ZERO
 
446
   /* times() return 0 on these machines */
 
447
   wbegin[i] = (sge_get_gmt() - inittime) * clock_tick;
 
448
#endif
 
449
 
 
450
   wprev[i]  = wbegin[i];
 
451
}                                                                              
 
452
 
 
453
/****** uti/time/duration_add_offset() ****************************************
 
454
*  NAME
 
455
*     duration_add_offset() -- add function for time add
 
456
*
 
457
*  SYNOPSIS
 
458
*     u_long32 duration_add_offset(u_long32 duration, u_long32 offset) 
 
459
*
 
460
*  FUNCTION
 
461
*     add function to catch ulong overflow. Returns max ulong value if necessary
 
462
*
 
463
*  INPUTS
 
464
*     u_long32 duration - duration in seconds
 
465
*     u_long32 offset   - offset in seconds
 
466
*
 
467
*  RESULT
 
468
*     u_long32 - value < U_LONG32_MAX
 
469
*
 
470
*  NOTES
 
471
*     MT-NOTE: duration_add_offset() is not MT safe 
 
472
*******************************************************************************/
 
473
u_long32 duration_add_offset(u_long32 duration, u_long32 offset)
 
474
{
 
475
   if (duration == U_LONG32_MAX || offset == U_LONG32_MAX) {
 
476
      return U_LONG32_MAX;
 
477
   }
 
478
 
 
479
   if ((U_LONG32_MAX-offset) < duration) {
 
480
      duration = U_LONG32_MAX;
 
481
   } else {
 
482
      duration += offset;
 
483
   }
 
484
 
 
485
   return duration;
 
486
}