timers.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:4k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1999 Sendmail, Inc. and its suppliers.
  3.  * All rights reserved.
  4.  *
  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.
  8.  *
  9.  * Contributed by Exactis.com, Inc.
  10.  *
  11.  */
  12. #ifndef lint
  13. static char id[] = "@(#)$Id: timers.c,v 8.13 1999/11/23 07:22:28 gshapiro Exp $";
  14. #endif /* ! lint */
  15. #if _FFR_TIMERS
  16. # include <sys/types.h>
  17. # include <sys/time.h>
  18. # include "sendmail.h"
  19. # include <sys/resource.h> /* Must be after sendmail.h for NCR MP-RAS */
  20. static TIMER BaseTimer; /* current baseline */
  21. static int NTimers; /* current pointer into stack */
  22. static TIMER *TimerStack[MAXTIMERSTACK];
  23. static void
  24. # ifdef __STDC__
  25. warntimer(const char *msg, ...)
  26. # else /* __STDC__ */
  27. warntimer(msg, va_alist)
  28. const char *msg;
  29. va_dcl
  30. # endif /* __STDC__ */
  31. {
  32. char buf[MAXLINE];
  33. VA_LOCAL_DECL
  34. # if 0
  35. if (!tTd(98, 30))
  36. return;
  37. # endif /* 0 */
  38. VA_START(msg);
  39. vsnprintf(buf, sizeof buf, msg, ap);
  40. VA_END;
  41. sm_syslog(LOG_NOTICE, CurEnv->e_id, "%s; e_timers=0x%lx",
  42.   buf, (u_long) &CurEnv->e_timers);
  43. }
  44. static void
  45. zerotimer(ptimer)
  46. TIMER *ptimer;
  47. {
  48. memset(ptimer, '', sizeof *ptimer);
  49. }
  50. static void
  51. addtimer(ta, tb)
  52. TIMER *ta;
  53. TIMER *tb;
  54. {
  55. tb->ti_wall_sec += ta->ti_wall_sec;
  56. tb->ti_wall_usec += ta->ti_wall_usec;
  57. if (tb->ti_wall_usec > 1000000)
  58. {
  59. tb->ti_wall_sec++;
  60. tb->ti_wall_usec -= 1000000;
  61. }
  62. tb->ti_cpu_sec += ta->ti_cpu_sec;
  63. tb->ti_cpu_usec += ta->ti_cpu_usec;
  64. if (tb->ti_cpu_usec > 1000000)
  65. {
  66. tb->ti_cpu_sec++;
  67. tb->ti_cpu_usec -= 1000000;
  68. }
  69. }
  70. static void
  71. subtimer(ta, tb)
  72. TIMER *ta;
  73. TIMER *tb;
  74. {
  75. tb->ti_wall_sec -= ta->ti_wall_sec;
  76. tb->ti_wall_usec -= ta->ti_wall_usec;
  77. if (tb->ti_wall_usec < 0)
  78. {
  79. tb->ti_wall_sec--;
  80. tb->ti_wall_usec += 1000000;
  81. }
  82. tb->ti_cpu_sec -= ta->ti_cpu_sec;
  83. tb->ti_cpu_usec -= ta->ti_cpu_usec;
  84. if (tb->ti_cpu_usec < 0)
  85. {
  86. tb->ti_cpu_sec--;
  87. tb->ti_cpu_usec += 1000000;
  88. }
  89. }
  90. static int
  91. getcurtimer(ptimer)
  92. TIMER *ptimer;
  93. {
  94. struct rusage ru;
  95. struct timeval now;
  96. if (getrusage(RUSAGE_SELF, &ru) < 0 || gettimeofday(&now, NULL) < 0)
  97. return -1;
  98. ptimer->ti_wall_sec = now.tv_sec;
  99. ptimer->ti_wall_usec = now.tv_usec;
  100. ptimer->ti_cpu_sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
  101. ptimer->ti_cpu_usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
  102. if (ptimer->ti_cpu_usec > 1000000)
  103. {
  104. ptimer->ti_cpu_sec++;
  105. ptimer->ti_cpu_usec -= 1000000;
  106. }
  107. return 0;
  108. }
  109. static void
  110. getinctimer(ptimer)
  111. TIMER *ptimer;
  112. {
  113. TIMER cur;
  114. if (getcurtimer(&cur) < 0)
  115. {
  116. zerotimer(ptimer);
  117. return;
  118. }
  119. if (BaseTimer.ti_wall_sec == 0)
  120. {
  121. /* first call */
  122. memset(ptimer, '', sizeof *ptimer);
  123. }
  124. else
  125. {
  126. *ptimer = cur;
  127. subtimer(&BaseTimer, ptimer);
  128. }
  129. BaseTimer = cur;
  130. }
  131. void
  132. flushtimers()
  133. {
  134. NTimers = 0;
  135. (void) getcurtimer(&BaseTimer);
  136. }
  137. void
  138. pushtimer(ptimer)
  139. TIMER *ptimer;
  140. {
  141. int i;
  142. int save_errno = errno;
  143. TIMER incr;
  144. /* find how much time has changed since last call */
  145. getinctimer(&incr);
  146. /* add that into the old timers */
  147. i = NTimers;
  148. if (i > MAXTIMERSTACK)
  149. i = MAXTIMERSTACK;
  150. while (--i >= 0)
  151. {
  152. addtimer(&incr, TimerStack[i]);
  153. if (TimerStack[i] == ptimer)
  154. {
  155. warntimer("Timer@0x%lx already on stack, index=%d, NTimers=%d",
  156.   (u_long) ptimer, i, NTimers);
  157. errno = save_errno;
  158. return;
  159. }
  160. }
  161. errno = save_errno;
  162. /* handle stack overflow */
  163. if (NTimers >= MAXTIMERSTACK)
  164. return;
  165. /* now add the timer to the stack */
  166. TimerStack[NTimers++] = ptimer;
  167. }
  168. void
  169. poptimer(ptimer)
  170. TIMER *ptimer;
  171. {
  172. int i;
  173. int save_errno = errno;
  174. TIMER incr;
  175. /* find how much time has changed since last call */
  176. getinctimer(&incr);
  177. /* add that into the old timers */
  178. i = NTimers;
  179. if (i > MAXTIMERSTACK)
  180. i = MAXTIMERSTACK;
  181. while (--i >= 0)
  182. addtimer(&incr, TimerStack[i]);
  183. /* pop back to this timer */
  184. for (i = 0; i < NTimers; i++)
  185. if (TimerStack[i] == ptimer)
  186. break;
  187. if (i != NTimers - 1)
  188. warntimer("poptimer: odd pop (timer=0x%lx, index=%d, NTimers=%d)",
  189.   (u_long) ptimer, i, NTimers);
  190. NTimers = i;
  191. /* clean up and return */
  192. errno = save_errno;
  193. }
  194. char *
  195. strtimer(ptimer)
  196. TIMER *ptimer;
  197. {
  198. static char buf[40];
  199. snprintf(buf, sizeof buf, "%ld.%06ldr/%ld.%06ldc",
  200. ptimer->ti_wall_sec, ptimer->ti_wall_usec,
  201. ptimer->ti_cpu_sec, ptimer->ti_cpu_usec);
  202. return buf;
  203. }
  204. #endif /* _FFR_TIMERS */