blob: 399c3695224ef4ed61a3fa67f7fb9be14eaeb154 [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 %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% January 1993 %
18% %
19% %
cristyb56bb242014-11-25 17:12:48 +000020% Copyright 1999-2015 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*/
cristyfd1cb132014-11-04 14:12:40 +000054#if !defined(CLOCKS_PER_SEC)
55#define CLOCKS_PER_SEC 100
cristy3ed852e2009-09-05 21:47:34 +000056#endif
57
58/*
59 Forward declarations.
60*/
61static double
62 UserTime(void);
63
64static void
65 StopTimer(TimerInfo *);
66
67/*
68%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69% %
70% %
71% %
72% A c q u i r e T i m e r I n f o %
73% %
74% %
75% %
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77%
78% AcquireTimerInfo() initializes the TimerInfo structure. It effectively
79% creates a stopwatch and starts it.
80%
81% The format of the AcquireTimerInfo method is:
82%
83% TimerInfo *AcquireTimerInfo(void)
84%
85*/
86MagickExport TimerInfo *AcquireTimerInfo(void)
87{
88 TimerInfo
89 *timer_info;
90
cristy73bd4a52010-10-05 11:24:23 +000091 timer_info=(TimerInfo *) AcquireMagickMemory(sizeof(*timer_info));
cristy3ed852e2009-09-05 21:47:34 +000092 if (timer_info == (TimerInfo *) NULL)
93 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
94 (void) ResetMagickMemory(timer_info,0,sizeof(*timer_info));
95 timer_info->signature=MagickSignature;
96 GetTimerInfo(timer_info);
97 return(timer_info);
98}
99
100/*
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102% %
103% %
104% %
105% C o n t i n u e T i m e r %
106% %
107% %
108% %
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%
111% ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
112% counting from the last StartTimer() onwards.
113%
114% The format of the ContinueTimer method is:
115%
116% MagickBooleanType ContinueTimer(TimerInfo *time_info)
117%
118% A description of each parameter follows.
119%
120% o time_info: Time statistics structure.
121%
122*/
123MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
124{
125 assert(time_info != (TimerInfo *) NULL);
126 assert(time_info->signature == MagickSignature);
127 if (time_info->state == UndefinedTimerState)
128 return(MagickFalse);
129 if (time_info->state == StoppedTimerState)
130 {
131 time_info->user.total-=time_info->user.stop-time_info->user.start;
132 time_info->elapsed.total-=time_info->elapsed.stop-
133 time_info->elapsed.start;
134 }
135 time_info->state=RunningTimerState;
136 return(MagickTrue);
137}
138
139/*
140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141% %
142% %
143% %
144% D e s t r o y T i m e r I n f o %
145% %
146% %
147% %
148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149%
150% DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
151%
152% The format of the DestroyTimerInfo method is:
153%
154% TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
155%
156% A description of each parameter follows:
157%
158% o timer_info: The cipher context.
159%
160*/
161MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
162{
163 assert(timer_info != (TimerInfo *) NULL);
164 assert(timer_info->signature == MagickSignature);
165 timer_info->signature=(~MagickSignature);
166 timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
167 return(timer_info);
168}
169
170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175+ E l a p s e d T i m e %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% ElapsedTime() returns the elapsed time (in seconds) since the last call to
182% StartTimer().
183%
184% The format of the ElapsedTime method is:
185%
186% double ElapsedTime()
187%
188*/
189static double ElapsedTime(void)
190{
191#if defined(MAGICKCORE_HAVE_TIMES)
192 struct tms
193 timer;
194
cristyfd1cb132014-11-04 14:12:40 +0000195 return((double) times(&timer)/CLOCKS_PER_SEC);
cristy3ed852e2009-09-05 21:47:34 +0000196#else
cristy0157aea2010-04-24 21:12:18 +0000197#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000198 return(NTElapsedTime());
199#else
cristyfd1cb132014-11-04 14:12:40 +0000200 return((double) clock()/CLOCKS_PER_SEC);
cristy3ed852e2009-09-05 21:47:34 +0000201#endif
202#endif
203}
204
205/*
206%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207% %
208% %
209% %
210% G e t E l a p s e d T i m e %
211% %
212% %
213% %
214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215%
216% GetElapsedTime() returns the elapsed time (in seconds) passed between the
217% start and stop events. If the stopwatch is still running, it is stopped
218% first.
219%
220% The format of the GetElapsedTime method is:
221%
222% double GetElapsedTime(TimerInfo *time_info)
223%
224% A description of each parameter follows.
225%
226% o time_info: Timer statistics structure.
227%
228*/
229MagickExport double GetElapsedTime(TimerInfo *time_info)
230{
231 assert(time_info != (TimerInfo *) NULL);
232 assert(time_info->signature == MagickSignature);
233 if (time_info->state == UndefinedTimerState)
234 return(0.0);
235 if (time_info->state == RunningTimerState)
236 StopTimer(time_info);
237 return(time_info->elapsed.total);
238}
239
240/*
241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242% %
243% %
244% %
245+ G e t T i m e r I n f o %
246% %
247% %
248% %
249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250%
251% GetTimerInfo() initializes the TimerInfo structure.
252%
253% The format of the GetTimerInfo method is:
254%
255% void GetTimerInfo(TimerInfo *time_info)
256%
257% A description of each parameter follows.
258%
259% o time_info: Timer statistics structure.
260%
261*/
262MagickExport void GetTimerInfo(TimerInfo *time_info)
263{
264 /*
265 Create a stopwatch and start it.
266 */
267 assert(time_info != (TimerInfo *) NULL);
268 (void) ResetMagickMemory(time_info,0,sizeof(*time_info));
269 time_info->state=UndefinedTimerState;
270 time_info->signature=MagickSignature;
271 StartTimer(time_info,MagickTrue);
272}
273
274/*
275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276% %
277% %
278% %
279% G e t U s e r T i m e %
280% %
281% %
282% %
283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284%
285% GetUserTime() returns the User time (user and system) by the operating
286% system (in seconds) between the start and stop events. If the stopwatch is
287% still running, it is stopped first.
288%
289% The format of the GetUserTime method is:
290%
291% double GetUserTime(TimerInfo *time_info)
292%
293% A description of each parameter follows.
294%
295% o time_info: Timer statistics structure.
296%
297*/
298MagickExport double GetUserTime(TimerInfo *time_info)
299{
300 assert(time_info != (TimerInfo *) NULL);
301 assert(time_info->signature == MagickSignature);
302 if (time_info->state == UndefinedTimerState)
303 return(0.0);
304 if (time_info->state == RunningTimerState)
305 StopTimer(time_info);
306 return(time_info->user.total);
307}
308
309/*
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311% %
312% %
313% %
314% R e s e t T i m e r %
315% %
316% %
317% %
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319%
320% ResetTimer() resets the stopwatch.
321%
322% The format of the ResetTimer method is:
323%
324% void ResetTimer(TimerInfo *time_info)
325%
326% A description of each parameter follows.
327%
328% o time_info: Timer statistics structure.
329%
330*/
331MagickExport void ResetTimer(TimerInfo *time_info)
332{
333 assert(time_info != (TimerInfo *) NULL);
334 assert(time_info->signature == MagickSignature);
335 StopTimer(time_info);
336 time_info->elapsed.stop=0.0;
337 time_info->user.stop=0.0;
338}
339
340/*
341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342% %
343% %
344% %
345+ S t a r t T i m e r %
346% %
347% %
348% %
349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350%
351% StartTimer() starts the stopwatch.
352%
353% The format of the StartTimer method is:
354%
355% void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
356%
357% A description of each parameter follows.
358%
359% o time_info: Timer statistics structure.
360%
361% o reset: If reset is MagickTrue, then the stopwatch is reset prior to
362% starting. If reset is MagickFalse, then timing is continued without
363% resetting the stopwatch.
364%
365*/
366MagickExport void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
367{
368 assert(time_info != (TimerInfo *) NULL);
369 assert(time_info->signature == MagickSignature);
370 if (reset != MagickFalse)
371 {
372 /*
373 Reset the stopwatch before starting it.
374 */
375 time_info->user.total=0.0;
376 time_info->elapsed.total=0.0;
377 }
378 if (time_info->state != RunningTimerState)
379 {
380 time_info->elapsed.start=ElapsedTime();
381 time_info->user.start=UserTime();
382 }
383 time_info->state=RunningTimerState;
384}
385
386/*
387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388% %
389% %
390% %
391+ S t o p T i m e r %
392% %
393% %
394% %
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396%
397% StopTimer() stops the stopwatch.
398%
399% The format of the StopTimer method is:
400%
401% void StopTimer(TimerInfo *time_info)
402%
403% A description of each parameter follows.
404%
405% o time_info: Timer statistics structure.
406%
407*/
408static void StopTimer(TimerInfo *time_info)
409{
410 assert(time_info != (TimerInfo *) NULL);
411 assert(time_info->signature == MagickSignature);
412 time_info->elapsed.stop=ElapsedTime();
413 time_info->user.stop=UserTime();
414 if (time_info->state == RunningTimerState)
415 {
416 time_info->user.total+=time_info->user.stop-
417 time_info->user.start+MagickEpsilon;
418 time_info->elapsed.total+=time_info->elapsed.stop-
419 time_info->elapsed.start+MagickEpsilon;
420 }
421 time_info->state=StoppedTimerState;
422}
423
424/*
425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426% %
427% %
428% %
429+ U s e r T i m e %
430% %
431% %
432% %
433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434%
435% UserTime() returns the total time the process has been scheduled (in
436% seconds) since the last call to StartTimer().
437%
438% The format of the UserTime method is:
439%
440% double UserTime()
441%
442*/
443static double UserTime(void)
444{
445#if defined(MAGICKCORE_HAVE_TIMES)
446 struct tms
447 timer;
448
449 (void) times(&timer);
cristyfd1cb132014-11-04 14:12:40 +0000450 return((double) (timer.tms_utime+timer.tms_stime)/CLOCKS_PER_SEC);
cristy3ed852e2009-09-05 21:47:34 +0000451#else
cristy0157aea2010-04-24 21:12:18 +0000452#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000453 return(NTUserTime());
454#else
cristyfd1cb132014-11-04 14:12:40 +0000455 return((double) clock()/CLOCKS_PER_SEC);
cristy3ed852e2009-09-05 21:47:34 +0000456#endif
457#endif
458}