2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % TTTTT IIIII M M EEEEE RRRR %
10 % T IIIII M M EEEEE R R %
13 % MagickCore Timing Methods %
20 % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 % Contributed by Bill Radcliffe and Bob Friesenhahn.
43 #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"
48 #include "MagickCore/nt-base-private.h"
49 #include "MagickCore/timer.h"
54 #if defined(macintosh)
55 #define CLK_TCK CLOCKS_PER_SEC
58 #define CLK_TCK sysconf(_SC_CLK_TCK)
68 StopTimer(TimerInfo *);
71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75 % A c q u i r e T i m e r I n f o %
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 % AcquireTimerInfo() initializes the TimerInfo structure. It effectively
82 % creates a stopwatch and starts it.
84 % The format of the AcquireTimerInfo method is:
86 % TimerInfo *AcquireTimerInfo(void)
89 MagickExport TimerInfo *AcquireTimerInfo(void)
94 timer_info=(TimerInfo *) AcquireMagickMemory(sizeof(*timer_info));
95 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);
104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 % C o n t i n u e T i m e r %
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 % ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
115 % counting from the last StartTimer() onwards.
117 % The format of the ContinueTimer method is:
119 % MagickBooleanType ContinueTimer(TimerInfo *time_info)
121 % A description of each parameter follows.
123 % o time_info: Time statistics structure.
126 MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
128 assert(time_info != (TimerInfo *) NULL);
129 assert(time_info->signature == MagickSignature);
130 if (time_info->state == UndefinedTimerState)
132 if (time_info->state == StoppedTimerState)
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;
138 time_info->state=RunningTimerState;
143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 % D e s t r o y T i m e r I n f o %
151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 % DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
155 % The format of the DestroyTimerInfo method is:
157 % TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
159 % A description of each parameter follows:
161 % o timer_info: The cipher context.
164 MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
166 assert(timer_info != (TimerInfo *) NULL);
167 assert(timer_info->signature == MagickSignature);
168 timer_info->signature=(~MagickSignature);
169 timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 + E l a p s e d T i m e %
182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 % ElapsedTime() returns the elapsed time (in seconds) since the last call to
187 % The format of the ElapsedTime method is:
189 % double ElapsedTime()
192 static double ElapsedTime(void)
194 #if defined(MAGICKCORE_HAVE_TIMES)
198 return((double) times(&timer)/CLK_TCK);
200 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
201 return(NTElapsedTime());
203 return((double) clock()/CLK_TCK);
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 % G e t E l a p s e d T i m e %
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
223 % The format of the GetElapsedTime method is:
225 % double GetElapsedTime(TimerInfo *time_info)
227 % A description of each parameter follows.
229 % o time_info: Timer statistics structure.
232 MagickExport double GetElapsedTime(TimerInfo *time_info)
234 assert(time_info != (TimerInfo *) NULL);
235 assert(time_info->signature == MagickSignature);
236 if (time_info->state == UndefinedTimerState)
238 if (time_info->state == RunningTimerState)
239 StopTimer(time_info);
240 return(time_info->elapsed.total);
244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248 + G e t T i m e r I n f o %
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254 % GetTimerInfo() initializes the TimerInfo structure.
256 % The format of the GetTimerInfo method is:
258 % void GetTimerInfo(TimerInfo *time_info)
260 % A description of each parameter follows.
262 % o time_info: Timer statistics structure.
265 MagickExport void GetTimerInfo(TimerInfo *time_info)
268 Create a stopwatch and start it.
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);
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 % G e t U s e r T i m e %
286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
292 % The format of the GetUserTime method is:
294 % double GetUserTime(TimerInfo *time_info)
296 % A description of each parameter follows.
298 % o time_info: Timer statistics structure.
301 MagickExport double GetUserTime(TimerInfo *time_info)
303 assert(time_info != (TimerInfo *) NULL);
304 assert(time_info->signature == MagickSignature);
305 if (time_info->state == UndefinedTimerState)
307 if (time_info->state == RunningTimerState)
308 StopTimer(time_info);
309 return(time_info->user.total);
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % R e s e t T i m e r %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 % ResetTimer() resets the stopwatch.
325 % The format of the ResetTimer method is:
327 % void ResetTimer(TimerInfo *time_info)
329 % A description of each parameter follows.
331 % o time_info: Timer statistics structure.
334 MagickExport void ResetTimer(TimerInfo *time_info)
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;
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348 + S t a r t T i m e r %
352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354 % StartTimer() starts the stopwatch.
356 % The format of the StartTimer method is:
358 % void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
360 % A description of each parameter follows.
362 % o time_info: Timer statistics structure.
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.
369 MagickExport void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
371 assert(time_info != (TimerInfo *) NULL);
372 assert(time_info->signature == MagickSignature);
373 if (reset != MagickFalse)
376 Reset the stopwatch before starting it.
378 time_info->user.total=0.0;
379 time_info->elapsed.total=0.0;
381 if (time_info->state != RunningTimerState)
383 time_info->elapsed.start=ElapsedTime();
384 time_info->user.start=UserTime();
386 time_info->state=RunningTimerState;
390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 + S t o p T i m e r %
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 % StopTimer() stops the stopwatch.
402 % The format of the StopTimer method is:
404 % void StopTimer(TimerInfo *time_info)
406 % A description of each parameter follows.
408 % o time_info: Timer statistics structure.
411 static void StopTimer(TimerInfo *time_info)
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)
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;
424 time_info->state=StoppedTimerState;
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438 % UserTime() returns the total time the process has been scheduled (in
439 % seconds) since the last call to StartTimer().
441 % The format of the UserTime method is:
446 static double UserTime(void)
448 #if defined(MAGICKCORE_HAVE_TIMES)
452 (void) times(&timer);
453 return((double) (timer.tms_utime+timer.tms_stime)/CLK_TCK);
455 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
456 return(NTUserTime());
458 return((double) clock()/CLK_TCK);