2 * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
9 * Contributed by Exactis.com, Inc.
14 SM_RCSID("@(#)$Id: timers.c,v 8.24 2001/09/11 04:05:17 gshapiro Exp $")
17 # include <sys/types.h>
18 # include <sys/time.h>
19 # include "sendmail.h"
20 # include <sys/resource.h> /* Must be after sendmail.h for NCR MP-RAS */
22 static TIMER BaseTimer
; /* current baseline */
23 static int NTimers
; /* current pointer into stack */
24 static TIMER
*TimerStack
[MAXTIMERSTACK
];
28 warntimer(const char *msg
, ...)
30 warntimer(msg
, va_alist
)
33 # endif /* __STDC__ */
43 (void) sm_vsnprintf(buf
, sizeof buf
, msg
, ap
);
45 sm_syslog(LOG_NOTICE
, CurEnv
->e_id
, "%s; e_timers=0x%lx",
46 buf
, (unsigned long) &CurEnv
->e_timers
);
53 memset(ptimer
, '\0', sizeof *ptimer
);
61 tb
->ti_wall_sec
+= ta
->ti_wall_sec
;
62 tb
->ti_wall_usec
+= ta
->ti_wall_usec
;
63 if (tb
->ti_wall_usec
> 1000000)
66 tb
->ti_wall_usec
-= 1000000;
68 tb
->ti_cpu_sec
+= ta
->ti_cpu_sec
;
69 tb
->ti_cpu_usec
+= ta
->ti_cpu_usec
;
70 if (tb
->ti_cpu_usec
> 1000000)
73 tb
->ti_cpu_usec
-= 1000000;
82 tb
->ti_wall_sec
-= ta
->ti_wall_sec
;
83 tb
->ti_wall_usec
-= ta
->ti_wall_usec
;
84 if (tb
->ti_wall_usec
< 0)
87 tb
->ti_wall_usec
+= 1000000;
89 tb
->ti_cpu_sec
-= ta
->ti_cpu_sec
;
90 tb
->ti_cpu_usec
-= ta
->ti_cpu_usec
;
91 if (tb
->ti_cpu_usec
< 0)
94 tb
->ti_cpu_usec
+= 1000000;
105 if (getrusage(RUSAGE_SELF
, &ru
) < 0 || gettimeofday(&now
, NULL
) < 0)
107 ptimer
->ti_wall_sec
= now
.tv_sec
;
108 ptimer
->ti_wall_usec
= now
.tv_usec
;
109 ptimer
->ti_cpu_sec
= ru
.ru_utime
.tv_sec
+ ru
.ru_stime
.tv_sec
;
110 ptimer
->ti_cpu_usec
= ru
.ru_utime
.tv_usec
+ ru
.ru_stime
.tv_usec
;
111 if (ptimer
->ti_cpu_usec
> 1000000)
113 ptimer
->ti_cpu_sec
++;
114 ptimer
->ti_cpu_usec
-= 1000000;
125 if (getcurtimer(&cur
) < 0)
130 if (BaseTimer
.ti_wall_sec
== 0)
133 memset(ptimer
, '\0', sizeof *ptimer
);
138 subtimer(&BaseTimer
, ptimer
);
147 (void) getcurtimer(&BaseTimer
);
155 int save_errno
= errno
;
158 /* find how much time has changed since last call */
161 /* add that into the old timers */
163 if (i
> MAXTIMERSTACK
)
167 addtimer(&incr
, TimerStack
[i
]);
168 if (TimerStack
[i
] == ptimer
)
170 warntimer("Timer@0x%lx already on stack, index=%d, NTimers=%d",
171 (unsigned long) ptimer
, i
, NTimers
);
178 /* handle stack overflow */
179 if (NTimers
>= MAXTIMERSTACK
)
182 /* now add the timer to the stack */
183 TimerStack
[NTimers
++] = ptimer
;
191 int save_errno
= errno
;
194 /* find how much time has changed since last call */
197 /* add that into the old timers */
199 if (i
> MAXTIMERSTACK
)
202 addtimer(&incr
, TimerStack
[i
]);
204 /* pop back to this timer */
205 for (i
= 0; i
< NTimers
; i
++)
207 if (TimerStack
[i
] == ptimer
)
211 if (i
!= NTimers
- 1)
212 warntimer("poptimer: odd pop (timer=0x%lx, index=%d, NTimers=%d)",
213 (unsigned long) ptimer
, i
, NTimers
);
216 /* clean up and return */
226 (void) sm_snprintf(buf
, sizeof buf
, "%ld.%06ldr/%ld.%06ldc",
227 ptimer
->ti_wall_sec
, ptimer
->ti_wall_usec
,
228 ptimer
->ti_cpu_sec
, ptimer
->ti_cpu_usec
);
231 #endif /* _FFR_TIMERS */