1/* proctm.c
2   Get the time spent in the process.
3
4   Copyright (C) 1992, 1993 Ian Lance Taylor
5
6   This file is part of the Taylor UUCP package.
7
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21
22   The author of the program may be contacted at ian@airs.com.
23   */
24
25#include "uucp.h"
26
27#include "sysdep.h"
28#include "system.h"
29
30#if HAVE_SYS_PARAM_H
31#include <sys/param.h>
32#endif
33
34#if HAVE_LIMITS_H
35#include <limits.h>
36#endif
37
38/* Prefer gettimeofday to ftime to times.  */
39
40#if HAVE_GETTIMEOFDAY || HAVE_FTIME
41#undef HAVE_TIMES
42#define HAVE_TIMES 0
43#endif
44
45#if HAVE_GETTIMEOFDAY
46#undef HAVE_FTIME
47#define HAVE_FTIME 0
48#endif
49
50#if HAVE_TIME_H && (TIME_WITH_SYS_TIME || ! HAVE_GETTIMEOFDAY)
51#include <time.h>
52#endif
53
54#if HAVE_GETTIMEOFDAY
55#include <sys/time.h>
56#endif
57
58#if HAVE_FTIME
59#include <sys/timeb.h>
60#endif
61
62#if HAVE_TIMES
63
64#if HAVE_SYS_TIMES_H
65#include <sys/times.h>
66#endif
67
68#if TIMES_DECLARATION_OK
69/* We use a macro to protect this because times really returns clock_t
70   and on some systems, such as Ultrix 4.0, clock_t is int.  We don't
71   leave it out entirely because on some systems, such as System III,
72   the declaration is necessary for correct compilation.  */
73#ifndef times
74extern long times ();
75#endif
76#endif /* TIMES_DECLARATION_OK */
77
78#ifdef _SC_CLK_TCK
79#define HAVE_SC_CLK_TCK 1
80#else
81#define HAVE_SC_CLK_TCK 0
82#endif
83
84/* TIMES_TICK may have been set in policy.h, or we may be able to get
85   it using sysconf.  If neither is the case, try to find a useful
86   definition from the system header files.  */
87#if TIMES_TICK == 0 && (! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK)
88#ifdef CLK_TCK
89#undef TIMES_TICK
90#define TIMES_TICK CLK_TCK
91#else /* ! defined (CLK_TCK) */
92#ifdef HZ
93#undef TIMES_TICK
94#define TIMES_TICK HZ
95#endif /* defined (HZ) */
96#endif /* ! defined (CLK_TCK) */
97#endif /* TIMES_TICK == 0 && (! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK) */
98
99#endif /* HAVE_TIMES */
100
101#ifndef time
102extern time_t time ();
103#endif
104#if HAVE_SYSCONF
105#ifndef sysconf
106extern long sysconf ();
107#endif
108#endif
109
110/* Get the time in seconds and microseconds; this need only work
111   within the process when called from the system independent code.
112   It is also called by ixsysdep_time.  */
113
114long
115ixsysdep_process_time (pimicros)
116     long *pimicros;
117{
118#if HAVE_GETTIMEOFDAY
119  struct timeval stime;
120  struct timezone stz;
121
122  (void) gettimeofday (&stime, &stz);
123  if (pimicros != NULL)
124    *pimicros = (long) stime.tv_usec;
125  return (long) stime.tv_sec;
126#endif /* HAVE_GETTIMEOFDAY */
127
128#if HAVE_FTIME
129  static boolean fbad;
130
131  if (! fbad)
132    {
133      struct timeb stime;
134      static struct timeb slast;
135
136      (void) ftime (&stime);
137
138      /* On some systems, such as SCO 3.2.2, ftime can go backwards in
139	 time.  If we detect this, we switch to using time.  */
140      if (slast.time != 0
141	  && (stime.time < slast.time
142	      || (stime.time == slast.time &&
143		  stime.millitm < slast.millitm)))
144	fbad = TRUE;
145      else
146	{
147	  slast = stime;
148	  if (pimicros != NULL)
149	    *pimicros = (long) stime.millitm * (long) 1000;
150	  return (long) stime.time;
151	}
152    }
153
154  if (pimicros != NULL)
155    *pimicros = 0;
156  return (long) time ((time_t *) NULL);
157#endif /* HAVE_FTIME */
158
159#if HAVE_TIMES
160  struct tms s;
161  long i;
162  static int itick;
163
164  if (itick == 0)
165    {
166#if TIMES_TICK == 0
167#if HAVE_SYSCONF && HAVE_SC_CLK_TCK
168      itick = (int) sysconf (_SC_CLK_TCK);
169#else /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */
170      const char *z;
171
172      z = getenv ("HZ");
173      if (z != NULL)
174	itick = (int) strtol (z, (char **) NULL, 10);
175
176      /* If we really couldn't get anything, just use 60.  */
177      if (itick == 0)
178	itick = 60;
179#endif /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */
180#else /* TIMES_TICK != 0 */
181      itick = TIMES_TICK;
182#endif /* TIMES_TICK == 0 */
183    }
184
185  i = (long) times (&s);
186  if (pimicros != NULL)
187    *pimicros = (i % (long) itick) * ((long) 1000000 / (long) itick);
188  return i / (long) itick;
189#endif /* HAVE_TIMES */
190
191#if ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES
192  if (pimicros != NULL)
193    *pimicros = 0;
194  return (long) time ((time_t *) NULL);
195#endif /* ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES  */
196}
197