2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % TTTTT IIIII M M EEEEE RRRR %
10 % T IIIII M M EEEEE R R %
13 % MagickCore Timing Methods %
20 % Copyright 1999-2015 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(CLOCKS_PER_SEC)
55 #define CLOCKS_PER_SEC 100
65 StopTimer(TimerInfo *);
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 % A c q u i r e T i m e r I n f o %
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % AcquireTimerInfo() initializes the TimerInfo structure. It effectively
79 % creates a stopwatch and starts it.
81 % The format of the AcquireTimerInfo method is:
83 % TimerInfo *AcquireTimerInfo(void)
86 MagickExport TimerInfo *AcquireTimerInfo(void)
91 timer_info=(TimerInfo *) AcquireMagickMemory(sizeof(*timer_info));
92 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);
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105 % C o n t i n u e T i m e r %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111 % ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
112 % counting from the last StartTimer() onwards.
114 % The format of the ContinueTimer method is:
116 % MagickBooleanType ContinueTimer(TimerInfo *time_info)
118 % A description of each parameter follows.
120 % o time_info: Time statistics structure.
123 MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
125 assert(time_info != (TimerInfo *) NULL);
126 assert(time_info->signature == MagickSignature);
127 if (time_info->state == UndefinedTimerState)
129 if (time_info->state == StoppedTimerState)
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;
135 time_info->state=RunningTimerState;
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144 % D e s t r o y T i m e r I n f o %
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 % DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
152 % The format of the DestroyTimerInfo method is:
154 % TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
156 % A description of each parameter follows:
158 % o timer_info: The cipher context.
161 MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
163 assert(timer_info != (TimerInfo *) NULL);
164 assert(timer_info->signature == MagickSignature);
165 timer_info->signature=(~MagickSignature);
166 timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 + E l a p s e d T i m e %
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 % ElapsedTime() returns the elapsed time (in seconds) since the last call to
184 % The format of the ElapsedTime method is:
186 % double ElapsedTime()
189 static double ElapsedTime(void)
191 #if defined(MAGICKCORE_HAVE_TIMES)
195 return((double) times(&timer)/CLOCKS_PER_SEC);
197 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
198 return(NTElapsedTime());
200 return((double) clock()/CLOCKS_PER_SEC);
206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % G e t E l a p s e d T i m e %
214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
220 % The format of the GetElapsedTime method is:
222 % double GetElapsedTime(TimerInfo *time_info)
224 % A description of each parameter follows.
226 % o time_info: Timer statistics structure.
229 MagickExport double GetElapsedTime(TimerInfo *time_info)
231 assert(time_info != (TimerInfo *) NULL);
232 assert(time_info->signature == MagickSignature);
233 if (time_info->state == UndefinedTimerState)
235 if (time_info->state == RunningTimerState)
236 StopTimer(time_info);
237 return(time_info->elapsed.total);
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 + G e t T i m e r I n f o %
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 % GetTimerInfo() initializes the TimerInfo structure.
253 % The format of the GetTimerInfo method is:
255 % void GetTimerInfo(TimerInfo *time_info)
257 % A description of each parameter follows.
259 % o time_info: Timer statistics structure.
262 MagickExport void GetTimerInfo(TimerInfo *time_info)
265 Create a stopwatch and start it.
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);
275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 % G e t U s e r T i m e %
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
289 % The format of the GetUserTime method is:
291 % double GetUserTime(TimerInfo *time_info)
293 % A description of each parameter follows.
295 % o time_info: Timer statistics structure.
298 MagickExport double GetUserTime(TimerInfo *time_info)
300 assert(time_info != (TimerInfo *) NULL);
301 assert(time_info->signature == MagickSignature);
302 if (time_info->state == UndefinedTimerState)
304 if (time_info->state == RunningTimerState)
305 StopTimer(time_info);
306 return(time_info->user.total);
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 % R e s e t T i m e r %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % ResetTimer() resets the stopwatch.
322 % The format of the ResetTimer method is:
324 % void ResetTimer(TimerInfo *time_info)
326 % A description of each parameter follows.
328 % o time_info: Timer statistics structure.
331 MagickExport void ResetTimer(TimerInfo *time_info)
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;
341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 + S t a r t T i m e r %
349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 % StartTimer() starts the stopwatch.
353 % The format of the StartTimer method is:
355 % void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
357 % A description of each parameter follows.
359 % o time_info: Timer statistics structure.
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.
366 MagickExport void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
368 assert(time_info != (TimerInfo *) NULL);
369 assert(time_info->signature == MagickSignature);
370 if (reset != MagickFalse)
373 Reset the stopwatch before starting it.
375 time_info->user.total=0.0;
376 time_info->elapsed.total=0.0;
378 if (time_info->state != RunningTimerState)
380 time_info->elapsed.start=ElapsedTime();
381 time_info->user.start=UserTime();
383 time_info->state=RunningTimerState;
387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391 + S t o p T i m e r %
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 % StopTimer() stops the stopwatch.
399 % The format of the StopTimer method is:
401 % void StopTimer(TimerInfo *time_info)
403 % A description of each parameter follows.
405 % o time_info: Timer statistics structure.
408 static void StopTimer(TimerInfo *time_info)
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)
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;
421 time_info->state=StoppedTimerState;
425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % UserTime() returns the total time the process has been scheduled (in
436 % seconds) since the last call to StartTimer().
438 % The format of the UserTime method is:
443 static double UserTime(void)
445 #if defined(MAGICKCORE_HAVE_TIMES)
449 (void) times(&timer);
450 return((double) (timer.tms_utime+timer.tms_stime)/CLOCKS_PER_SEC);
452 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
453 return(NTUserTime());
455 return((double) clock()/CLOCKS_PER_SEC);