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-2005 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 timers = Timer();
37 Timer::Timer()
38 {
39 Reset();
40 }
43 void Timer::Reset(void)
44 {
45 for (int i = 0; i < tmCount; i++)
46 {
47 //tTotal[i] = 0;
48 cTotal[i] = cPath[i] = 0;
49 cTally[i] = cPathTally[i] = 0;
50 cMax[i] = cPathMax[i] = 0;
51 }
52 running = false;
53 count = 0;
54 type = lasttype = tmNon;
55 }
58 void Timer::Register(const int t, const bool start)
59 {
60 assert(t != tmNon);
62 if (type == tmNon)
63 {
64 type = t;
65 }
66 else
67 {
68 type = tmSev;
69 }
71 if (start)
72 {
73 Start();
74 }
75 }
77 void Timer::Start(void)
78 {
79 if (running)
80 {
81 fprintf(stderr, "ERROR: Timer already running in Timer::Start()\n");
82 abort();
83 }
84 cStart[type] = clock(); // CPU time
85 running = true;
86 }
89 void Timer::Stop(void)
90 {
91 if (!running)
92 {
93 fprintf(stderr, "ERROR: Timer not running in Timer::Stop()\n");
94 abort();
95 }
96 clock_t cStop = clock(); // CPU time
97 running = false;
99 bigclock_t cDiff;
100 if (cStop < cStart[type])
101 {
102 // Uh-oh, the clock value has wrapped around.
103 //
104 bigclock_t realStop = ((bigclock_t) cStop) + ULONG_MAX + 1;
105 cDiff = realStop - cStart[type];
106 }
107 else
108 {
109 cDiff = cStop - cStart[type];
110 }
112 if (cDiff > LONG_MAX)
113 {
114 fprintf(stderr, "Error: cDiff overflow in Timer:Stop()\n");
115 abort();
116 }
118 if (type == tmPth)
119 {
120 cPath[lasttype] += cDiff;
121 cPathTally[lasttype]++;
122 if (((clock_t) cDiff) > cPathMax[lasttype])
123 {
124 cPathMax[lasttype] = (clock_t) cDiff;
125 }
126 }
127 else
128 {
129 cTotal[type] += cDiff;
130 cTally[type]++;
131 if (((clock_t) cDiff) > cMax[type])
132 {
133 cMax[type] = (clock_t) cDiff;
134 }
135 lasttype = type;
136 }
138 type = tmNon;
139 }
142 void Timer::PrintAll(void)
143 {
144 for (int i = 0; i < tmCount; i++)
145 {
146 Print(i);
147 }
148 }
151 #define toMsec(tot) ((bigclock_t) ((tot) / (((double) CLOCKS_PER_SEC) / 1000)))
152 #define toAvg(tot, cnt) ((((cnt) > 0) ? ((long double) (tot)) / (cnt) : 0))
154 void Timer::Print(const int t)
155 {
156 bigclock_t avg = toMsec(toAvg(cTotal[t], cTally[t]));
157 bigclock_t pind = toMsec(toAvg(cPath[t], cPathTally[t]));
158 bigclock_t pavg = toMsec(toAvg(cPath[t], cTally[t]));
159 double max = toMsec(cMax[t]);
160 double pmax = toMsec(cPathMax[t]);
161 printf("\t%lld %d %lld %.0f %lld %d %lld %.0f %lld\n",
162 cTotal[t], cTally[t], avg, max,
163 cPath[t], cPathTally[t], pavg, pmax, pind);
164 }
167 }