2 * Copyright (c) 1999-2001 Proofpoint, 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.27 2013-11-22 20:51:57 ca Exp $")
17 # include <sys/types.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 */