MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
timer.c
Go to the documentation of this file.
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://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 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/exception.h"
46 #include "MagickCore/log.h"
47 #include "MagickCore/memory_.h"
50 #include "MagickCore/timer.h"
51 
52 /*
53  Define declarations.
54 */
55 #if !defined(CLOCKS_PER_SEC)
56 #define CLOCKS_PER_SEC 100
57 #endif
58 
59 /*
60  Forward declarations.
61 */
62 static double
63  UserTime(void);
64 
65 static void
67 
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 */
88 {
89  TimerInfo
90  *timer_info;
91 
92  timer_info=(TimerInfo *) AcquireCriticalMemory(sizeof(*timer_info));
93  (void) ResetMagickMemory(timer_info,0,sizeof(*timer_info));
94  timer_info->signature=MagickCoreSignature;
95  GetTimerInfo(timer_info);
96  return(timer_info);
97 }
98 
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 */
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 
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 */
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 
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 
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 */
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 
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 */
281 {
282  /*
283  Create a stopwatch and start it.
284  */
285  assert(time_info != (TimerInfo *) NULL);
286  (void) ResetMagickMemory(time_info,0,sizeof(*time_info));
287  time_info->state=UndefinedTimerState;
288  time_info->signature=MagickCoreSignature;
289  StartTimer(time_info,MagickTrue);
290 }
291 
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 */
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 
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 */
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 
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 */
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 
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 
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 }
MagickExport double GetUserTime(TimerInfo *time_info)
Definition: timer.c:316
double stop
Definition: timer.h:35
static double ElapsedTime(void)
Definition: timer.c:188
size_t signature
Definition: timer.h:50
MagickExport TimerInfo * DestroyTimerInfo(TimerInfo *timer_info)
Definition: timer.c:160
MagickExport TimerInfo * AcquireTimerInfo(void)
Definition: timer.c:87
double total
Definition: timer.h:35
MagickExport void StartTimer(TimerInfo *time_info, const MagickBooleanType reset)
Definition: timer.c:384
static double UserTime(void)
Definition: timer.c:461
#define MagickEpsilon
Definition: magick-type.h:110
#define MagickCoreSignature
MagickBooleanType
Definition: magick-type.h:156
Timer user
Definition: timer.h:43
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1164
MagickExport MagickBooleanType static void * AcquireCriticalMemory(const size_t size)
MagickExport void ResetTimer(TimerInfo *time_info)
Definition: timer.c:349
MagickExport void GetTimerInfo(TimerInfo *time_info)
Definition: timer.c:280
MagickExport double GetElapsedTime(TimerInfo *time_info)
Definition: timer.c:247
Timer elapsed
Definition: timer.h:43
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
#define CLOCKS_PER_SEC
Definition: timer.c:56
#define MagickExport
static void StopTimer(TimerInfo *)
Definition: timer.c:426
double start
Definition: timer.h:35
TimerState state
Definition: timer.h:47
MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
Definition: timer.c:122