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