1 /*
2 * vim: ts=4 sw=4 et tw=0 wm=0
3 *
4 * libavoid - Fast, Incremental, Object-avoiding Line Router
5 * Copyright (C) 2004-2006 Michael Wybrow <mjwybrow@users.sourceforge.net>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
23 #include <cstdio>
24 #include <cstdlib>
25 #include <cassert>
26 using std::abort;
27 #include <climits>
29 #include "libavoid/timer.h"
31 namespace Avoid {
34 Timer::Timer()
35 {
36 Reset();
37 }
40 void Timer::Reset(void)
41 {
42 for (int i = 0; i < tmCount; i++)
43 {
44 //tTotal[i] = 0;
45 cTotal[i] = cPath[i] = 0;
46 cTally[i] = cPathTally[i] = 0;
47 cMax[i] = cPathMax[i] = 0;
48 }
49 running = false;
50 count = 0;
51 type = lasttype = tmNon;
52 }
55 void Timer::Register(const int t, const bool start)
56 {
57 assert(t != tmNon);
59 if (type == tmNon)
60 {
61 type = t;
62 }
63 else
64 {
65 type = tmSev;
66 }
68 if (start)
69 {
70 Start();
71 }
72 }
74 void Timer::Start(void)
75 {
76 if (running)
77 {
78 fprintf(stderr, "ERROR: Timer already running in Timer::Start()\n");
79 abort();
80 }
81 cStart[type] = clock(); // CPU time
82 running = true;
83 }
86 void Timer::Stop(void)
87 {
88 if (!running)
89 {
90 fprintf(stderr, "ERROR: Timer not running in Timer::Stop()\n");
91 abort();
92 }
93 clock_t cStop = clock(); // CPU time
94 running = false;
96 bigclock_t cDiff;
97 if (cStop < cStart[type])
98 {
99 // Uh-oh, the clock value has wrapped around.
100 //
101 bigclock_t realStop = ((bigclock_t) cStop) + ULONG_MAX + 1;
102 cDiff = realStop - cStart[type];
103 }
104 else
105 {
106 cDiff = cStop - cStart[type];
107 }
109 if (cDiff > LONG_MAX)
110 {
111 fprintf(stderr, "Error: cDiff overflow in Timer:Stop()\n");
112 abort();
113 }
115 if (type == tmPth)
116 {
117 cPath[lasttype] += cDiff;
118 cPathTally[lasttype]++;
119 if (((clock_t) cDiff) > cPathMax[lasttype])
120 {
121 cPathMax[lasttype] = (clock_t) cDiff;
122 }
123 }
124 else
125 {
126 cTotal[type] += cDiff;
127 cTally[type]++;
128 if (((clock_t) cDiff) > cMax[type])
129 {
130 cMax[type] = (clock_t) cDiff;
131 }
132 lasttype = type;
133 }
135 type = tmNon;
136 }
139 void Timer::PrintAll(void)
140 {
141 for (int i = 0; i < tmCount; i++)
142 {
143 Print(i);
144 }
145 }
148 #define toMsec(tot) ((bigclock_t) ((tot) / (((double) CLOCKS_PER_SEC) / 1000)))
149 #define toAvg(tot, cnt) ((((cnt) > 0) ? ((long double) (tot)) / (cnt) : 0))
151 void Timer::Print(const int t)
152 {
153 bigclock_t avg = toMsec(toAvg(cTotal[t], cTally[t]));
154 bigclock_t pind = toMsec(toAvg(cPath[t], cPathTally[t]));
155 bigclock_t pavg = toMsec(toAvg(cPath[t], cTally[t]));
156 double max = toMsec(cMax[t]);
157 double pmax = toMsec(cPathMax[t]);
158 printf("\t%lld %d %lld %.0f %lld %d %lld %.0f %lld\n",
159 cTotal[t], cTally[t], avg, max,
160 cPath[t], cPathTally[t], pavg, pmax, pind);
161 }
164 }