blob: 57705e63c95d38cc1f04a878dd86071affbeb1bd [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% TTTTT IIIII M M EEEEE RRRR %
7% T I MM MM E R R %
8% T I M M M EEE RRRR %
9% T I M M E R R %
10% T IIIII M M EEEEE R R %
11% %
12% %
13% MagickCore Timing Methods %
14% %
15% Software Design %
16% John Cristy %
17% January 1993 %
18% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Contributed by Bill Radcliffe and Bob Friesenhahn.
37%
38*/
39
40/*
41 Include declarations.
42*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/exception.h"
45#include "MagickCore/exception-private.h"
46#include "MagickCore/log.h"
47#include "MagickCore/memory_.h"
cristy2c5fc272012-02-22 01:27:46 +000048#include "MagickCore/nt-base-private.h"
cristy4c08aed2011-07-01 19:47:50 +000049#include "MagickCore/timer.h"
cristy3ed852e2009-09-05 21:47:34 +000050
51/*
52 Define declarations.
53*/
54#if defined(macintosh)
55#define CLK_TCK CLOCKS_PER_SEC
56#endif
57#if !defined(CLK_TCK)
58#define CLK_TCK sysconf(_SC_CLK_TCK)
59#endif
60
61/*
62 Forward declarations.
63*/
64static double
65 UserTime(void);
66
67static void
68 StopTimer(TimerInfo *);
69
70/*
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72% %
73% %
74% %
75% A c q u i r e T i m e r I n f o %
76% %
77% %
78% %
79%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80%
81% AcquireTimerInfo() initializes the TimerInfo structure. It effectively
82% creates a stopwatch and starts it.
83%
84% The format of the AcquireTimerInfo method is:
85%
86% TimerInfo *AcquireTimerInfo(void)
87%
88*/
89MagickExport TimerInfo *AcquireTimerInfo(void)
90{
91 TimerInfo
92 *timer_info;
93
cristy73bd4a52010-10-05 11:24:23 +000094 timer_info=(TimerInfo *) AcquireMagickMemory(sizeof(*timer_info));
cristy3ed852e2009-09-05 21:47:34 +000095 if (timer_info == (TimerInfo *) NULL)
96 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
97 (void) ResetMagickMemory(timer_info,0,sizeof(*timer_info));
98 timer_info->signature=MagickSignature;
99 GetTimerInfo(timer_info);
100 return(timer_info);
101}
102
103/*
104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105% %
106% %
107% %
108% C o n t i n u e T i m e r %
109% %
110% %
111% %
112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113%
114% ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
115% counting from the last StartTimer() onwards.
116%
117% The format of the ContinueTimer method is:
118%
119% MagickBooleanType ContinueTimer(TimerInfo *time_info)
120%
121% A description of each parameter follows.
122%
123% o time_info: Time statistics structure.
124%
125*/
126MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
127{
128 assert(time_info != (TimerInfo *) NULL);
129 assert(time_info->signature == MagickSignature);
130 if (time_info->state == UndefinedTimerState)
131 return(MagickFalse);
132 if (time_info->state == StoppedTimerState)
133 {
134 time_info->user.total-=time_info->user.stop-time_info->user.start;
135 time_info->elapsed.total-=time_info->elapsed.stop-
136 time_info->elapsed.start;
137 }
138 time_info->state=RunningTimerState;
139 return(MagickTrue);
140}
141
142/*
143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144% %
145% %
146% %
147% D e s t r o y T i m e r I n f o %
148% %
149% %
150% %
151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
152%
153% DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
154%
155% The format of the DestroyTimerInfo method is:
156%
157% TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
158%
159% A description of each parameter follows:
160%
161% o timer_info: The cipher context.
162%
163*/
164MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
165{
166 assert(timer_info != (TimerInfo *) NULL);
167 assert(timer_info->signature == MagickSignature);
168 timer_info->signature=(~MagickSignature);
169 timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
170 return(timer_info);
171}
172
173/*
174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175% %
176% %
177% %
178+ E l a p s e d T i m e %
179% %
180% %
181% %
182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183%
184% ElapsedTime() returns the elapsed time (in seconds) since the last call to
185% StartTimer().
186%
187% The format of the ElapsedTime method is:
188%
189% double ElapsedTime()
190%
191*/
192static double ElapsedTime(void)
193{
194#if defined(MAGICKCORE_HAVE_TIMES)
195 struct tms
196 timer;
197
cristyf381eac2009-09-28 17:30:13 +0000198 return((double) times(&timer)/CLK_TCK);
cristy3ed852e2009-09-05 21:47:34 +0000199#else
cristy0157aea2010-04-24 21:12:18 +0000200#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000201 return(NTElapsedTime());
202#else
203 return((double) clock()/CLK_TCK);
204#endif
205#endif
206}
207
208/*
209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210% %
211% %
212% %
213% G e t E l a p s e d T i m e %
214% %
215% %
216% %
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218%
219% GetElapsedTime() returns the elapsed time (in seconds) passed between the
220% start and stop events. If the stopwatch is still running, it is stopped
221% first.
222%
223% The format of the GetElapsedTime method is:
224%
225% double GetElapsedTime(TimerInfo *time_info)
226%
227% A description of each parameter follows.
228%
229% o time_info: Timer statistics structure.
230%
231*/
232MagickExport double GetElapsedTime(TimerInfo *time_info)
233{
234 assert(time_info != (TimerInfo *) NULL);
235 assert(time_info->signature == MagickSignature);
236 if (time_info->state == UndefinedTimerState)
237 return(0.0);
238 if (time_info->state == RunningTimerState)
239 StopTimer(time_info);
240 return(time_info->elapsed.total);
241}
242
243/*
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245% %
246% %
247% %
248+ G e t T i m e r I n f o %
249% %
250% %
251% %
252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253%
254% GetTimerInfo() initializes the TimerInfo structure.
255%
256% The format of the GetTimerInfo method is:
257%
258% void GetTimerInfo(TimerInfo *time_info)
259%
260% A description of each parameter follows.
261%
262% o time_info: Timer statistics structure.
263%
264*/
265MagickExport void GetTimerInfo(TimerInfo *time_info)
266{
267 /*
268 Create a stopwatch and start it.
269 */
270 assert(time_info != (TimerInfo *) NULL);
271 (void) ResetMagickMemory(time_info,0,sizeof(*time_info));
272 time_info->state=UndefinedTimerState;
273 time_info->signature=MagickSignature;
274 StartTimer(time_info,MagickTrue);
275}
276
277/*
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279% %
280% %
281% %
282% G e t U s e r T i m e %
283% %
284% %
285% %
286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287%
288% GetUserTime() returns the User time (user and system) by the operating
289% system (in seconds) between the start and stop events. If the stopwatch is
290% still running, it is stopped first.
291%
292% The format of the GetUserTime method is:
293%
294% double GetUserTime(TimerInfo *time_info)
295%
296% A description of each parameter follows.
297%
298% o time_info: Timer statistics structure.
299%
300*/
301MagickExport double GetUserTime(TimerInfo *time_info)
302{
303 assert(time_info != (TimerInfo *) NULL);
304 assert(time_info->signature == MagickSignature);
305 if (time_info->state == UndefinedTimerState)
306 return(0.0);
307 if (time_info->state == RunningTimerState)
308 StopTimer(time_info);
309 return(time_info->user.total);
310}
311
312/*
313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314% %
315% %
316% %
317% R e s e t T i m e r %
318% %
319% %
320% %
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322%
323% ResetTimer() resets the stopwatch.
324%
325% The format of the ResetTimer method is:
326%
327% void ResetTimer(TimerInfo *time_info)
328%
329% A description of each parameter follows.
330%
331% o time_info: Timer statistics structure.
332%
333*/
334MagickExport void ResetTimer(TimerInfo *time_info)
335{
336 assert(time_info != (TimerInfo *) NULL);
337 assert(time_info->signature == MagickSignature);
338 StopTimer(time_info);
339 time_info->elapsed.stop=0.0;
340 time_info->user.stop=0.0;
341}
342
343/*
344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345% %
346% %
347% %
348+ S t a r t T i m e r %
349% %
350% %
351% %
352%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353%
354% StartTimer() starts the stopwatch.
355%
356% The format of the StartTimer method is:
357%
358% void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
359%
360% A description of each parameter follows.
361%
362% o time_info: Timer statistics structure.
363%
364% o reset: If reset is MagickTrue, then the stopwatch is reset prior to
365% starting. If reset is MagickFalse, then timing is continued without
366% resetting the stopwatch.
367%
368*/
369MagickExport void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
370{
371 assert(time_info != (TimerInfo *) NULL);
372 assert(time_info->signature == MagickSignature);
373 if (reset != MagickFalse)
374 {
375 /*
376 Reset the stopwatch before starting it.
377 */
378 time_info->user.total=0.0;
379 time_info->elapsed.total=0.0;
380 }
381 if (time_info->state != RunningTimerState)
382 {
383 time_info->elapsed.start=ElapsedTime();
384 time_info->user.start=UserTime();
385 }
386 time_info->state=RunningTimerState;
387}
388
389/*
390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391% %
392% %
393% %
394+ S t o p T i m e r %
395% %
396% %
397% %
398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399%
400% StopTimer() stops the stopwatch.
401%
402% The format of the StopTimer method is:
403%
404% void StopTimer(TimerInfo *time_info)
405%
406% A description of each parameter follows.
407%
408% o time_info: Timer statistics structure.
409%
410*/
411static void StopTimer(TimerInfo *time_info)
412{
413 assert(time_info != (TimerInfo *) NULL);
414 assert(time_info->signature == MagickSignature);
415 time_info->elapsed.stop=ElapsedTime();
416 time_info->user.stop=UserTime();
417 if (time_info->state == RunningTimerState)
418 {
419 time_info->user.total+=time_info->user.stop-
420 time_info->user.start+MagickEpsilon;
421 time_info->elapsed.total+=time_info->elapsed.stop-
422 time_info->elapsed.start+MagickEpsilon;
423 }
424 time_info->state=StoppedTimerState;
425}
426
427/*
428%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
429% %
430% %
431% %
432+ U s e r T i m e %
433% %
434% %
435% %
436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437%
438% UserTime() returns the total time the process has been scheduled (in
439% seconds) since the last call to StartTimer().
440%
441% The format of the UserTime method is:
442%
443% double UserTime()
444%
445*/
446static double UserTime(void)
447{
448#if defined(MAGICKCORE_HAVE_TIMES)
449 struct tms
450 timer;
451
452 (void) times(&timer);
453 return((double) (timer.tms_utime+timer.tms_stime)/CLK_TCK);
454#else
cristy0157aea2010-04-24 21:12:18 +0000455#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000456 return(NTUserTime());
457#else
458 return((double) clock()/CLK_TCK);
459#endif
460#endif
461}