summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/timers.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/timers.c')
-rw-r--r--contrib/sendmail/src/timers.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/contrib/sendmail/src/timers.c b/contrib/sendmail/src/timers.c
new file mode 100644
index 0000000..74d0ccf
--- /dev/null
+++ b/contrib/sendmail/src/timers.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1999 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ * Contributed by Exactis.com, Inc.
+ *
+ */
+
+#ifndef lint
+static char id[] = "@(#)$Id: timers.c,v 8.13 1999/11/23 07:22:28 gshapiro Exp $";
+#endif /* ! lint */
+
+#if _FFR_TIMERS
+# include <sys/types.h>
+# include <sys/time.h>
+# include "sendmail.h"
+# include <sys/resource.h> /* Must be after sendmail.h for NCR MP-RAS */
+
+static TIMER BaseTimer; /* current baseline */
+static int NTimers; /* current pointer into stack */
+static TIMER *TimerStack[MAXTIMERSTACK];
+
+static void
+# ifdef __STDC__
+warntimer(const char *msg, ...)
+# else /* __STDC__ */
+warntimer(msg, va_alist)
+ const char *msg;
+ va_dcl
+# endif /* __STDC__ */
+{
+ char buf[MAXLINE];
+ VA_LOCAL_DECL
+
+# if 0
+ if (!tTd(98, 30))
+ return;
+# endif /* 0 */
+ VA_START(msg);
+ vsnprintf(buf, sizeof buf, msg, ap);
+ VA_END;
+ sm_syslog(LOG_NOTICE, CurEnv->e_id, "%s; e_timers=0x%lx",
+ buf, (u_long) &CurEnv->e_timers);
+}
+
+static void
+zerotimer(ptimer)
+ TIMER *ptimer;
+{
+ memset(ptimer, '\0', sizeof *ptimer);
+}
+
+static void
+addtimer(ta, tb)
+ TIMER *ta;
+ TIMER *tb;
+{
+ tb->ti_wall_sec += ta->ti_wall_sec;
+ tb->ti_wall_usec += ta->ti_wall_usec;
+ if (tb->ti_wall_usec > 1000000)
+ {
+ tb->ti_wall_sec++;
+ tb->ti_wall_usec -= 1000000;
+ }
+ tb->ti_cpu_sec += ta->ti_cpu_sec;
+ tb->ti_cpu_usec += ta->ti_cpu_usec;
+ if (tb->ti_cpu_usec > 1000000)
+ {
+ tb->ti_cpu_sec++;
+ tb->ti_cpu_usec -= 1000000;
+ }
+}
+
+static void
+subtimer(ta, tb)
+ TIMER *ta;
+ TIMER *tb;
+{
+ tb->ti_wall_sec -= ta->ti_wall_sec;
+ tb->ti_wall_usec -= ta->ti_wall_usec;
+ if (tb->ti_wall_usec < 0)
+ {
+ tb->ti_wall_sec--;
+ tb->ti_wall_usec += 1000000;
+ }
+ tb->ti_cpu_sec -= ta->ti_cpu_sec;
+ tb->ti_cpu_usec -= ta->ti_cpu_usec;
+ if (tb->ti_cpu_usec < 0)
+ {
+ tb->ti_cpu_sec--;
+ tb->ti_cpu_usec += 1000000;
+ }
+}
+
+static int
+getcurtimer(ptimer)
+ TIMER *ptimer;
+{
+ struct rusage ru;
+ struct timeval now;
+
+ if (getrusage(RUSAGE_SELF, &ru) < 0 || gettimeofday(&now, NULL) < 0)
+ return -1;
+ ptimer->ti_wall_sec = now.tv_sec;
+ ptimer->ti_wall_usec = now.tv_usec;
+ ptimer->ti_cpu_sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
+ ptimer->ti_cpu_usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
+ if (ptimer->ti_cpu_usec > 1000000)
+ {
+ ptimer->ti_cpu_sec++;
+ ptimer->ti_cpu_usec -= 1000000;
+ }
+ return 0;
+}
+
+static void
+getinctimer(ptimer)
+ TIMER *ptimer;
+{
+ TIMER cur;
+
+ if (getcurtimer(&cur) < 0)
+ {
+ zerotimer(ptimer);
+ return;
+ }
+ if (BaseTimer.ti_wall_sec == 0)
+ {
+ /* first call */
+ memset(ptimer, '\0', sizeof *ptimer);
+ }
+ else
+ {
+ *ptimer = cur;
+ subtimer(&BaseTimer, ptimer);
+ }
+ BaseTimer = cur;
+}
+
+void
+flushtimers()
+{
+ NTimers = 0;
+ (void) getcurtimer(&BaseTimer);
+}
+
+void
+pushtimer(ptimer)
+ TIMER *ptimer;
+{
+ int i;
+ int save_errno = errno;
+ TIMER incr;
+
+ /* find how much time has changed since last call */
+ getinctimer(&incr);
+
+ /* add that into the old timers */
+ i = NTimers;
+ if (i > MAXTIMERSTACK)
+ i = MAXTIMERSTACK;
+ while (--i >= 0)
+ {
+ addtimer(&incr, TimerStack[i]);
+ if (TimerStack[i] == ptimer)
+ {
+ warntimer("Timer@0x%lx already on stack, index=%d, NTimers=%d",
+ (u_long) ptimer, i, NTimers);
+ errno = save_errno;
+ return;
+ }
+ }
+ errno = save_errno;
+
+ /* handle stack overflow */
+ if (NTimers >= MAXTIMERSTACK)
+ return;
+
+ /* now add the timer to the stack */
+ TimerStack[NTimers++] = ptimer;
+}
+
+void
+poptimer(ptimer)
+ TIMER *ptimer;
+{
+ int i;
+ int save_errno = errno;
+ TIMER incr;
+
+ /* find how much time has changed since last call */
+ getinctimer(&incr);
+
+ /* add that into the old timers */
+ i = NTimers;
+ if (i > MAXTIMERSTACK)
+ i = MAXTIMERSTACK;
+ while (--i >= 0)
+ addtimer(&incr, TimerStack[i]);
+
+ /* pop back to this timer */
+ for (i = 0; i < NTimers; i++)
+ if (TimerStack[i] == ptimer)
+ break;
+ if (i != NTimers - 1)
+ warntimer("poptimer: odd pop (timer=0x%lx, index=%d, NTimers=%d)",
+ (u_long) ptimer, i, NTimers);
+ NTimers = i;
+
+ /* clean up and return */
+ errno = save_errno;
+}
+
+char *
+strtimer(ptimer)
+ TIMER *ptimer;
+{
+ static char buf[40];
+
+ snprintf(buf, sizeof buf, "%ld.%06ldr/%ld.%06ldc",
+ ptimer->ti_wall_sec, ptimer->ti_wall_usec,
+ ptimer->ti_cpu_sec, ptimer->ti_cpu_usec);
+ return buf;
+}
+#endif /* _FFR_TIMERS */
OpenPOWER on IntegriCloud