MagickCore  7.0.3
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-2019 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 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/exception.h"
46 #include "MagickCore/locale_.h"
47 #include "MagickCore/log.h"
48 #include "MagickCore/memory_.h"
52 #include "MagickCore/timer.h"
54 
55 /*
56  Define declarations.
57 */
58 #if !defined(CLOCKS_PER_SEC)
59 #define CLOCKS_PER_SEC 100
60 #endif
61 
62 /*
63  Forward declarations.
64 */
65 static double
66  UserTime(void);
67 
68 static void
70 
71 /*
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 % %
74 % %
75 % %
76 % A c q u i r e T i m e r I n f o %
77 % %
78 % %
79 % %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %
82 % AcquireTimerInfo() initializes the TimerInfo structure. It effectively
83 % creates a stopwatch and starts it.
84 %
85 % The format of the AcquireTimerInfo method is:
86 %
87 % TimerInfo *AcquireTimerInfo(void)
88 %
89 */
91 {
92  TimerInfo
93  *timer_info;
94 
95  timer_info=(TimerInfo *) AcquireCriticalMemory(sizeof(*timer_info));
96  (void) memset(timer_info,0,sizeof(*timer_info));
97  timer_info->signature=MagickCoreSignature;
98  GetTimerInfo(timer_info);
99  return(timer_info);
100 }
101 
102 /*
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 % %
105 % %
106 % %
107 % C o n t i n u e T i m e r %
108 % %
109 % %
110 % %
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112 %
113 % ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
114 % counting from the last StartTimer() onwards.
115 %
116 % The format of the ContinueTimer method is:
117 %
118 % MagickBooleanType ContinueTimer(TimerInfo *time_info)
119 %
120 % A description of each parameter follows.
121 %
122 % o time_info: Time statistics structure.
123 %
124 */
126 {
127  assert(time_info != (TimerInfo *) NULL);
128  assert(time_info->signature == MagickCoreSignature);
129  if (time_info->state == UndefinedTimerState)
130  return(MagickFalse);
131  if (time_info->state == StoppedTimerState)
132  {
133  time_info->user.total-=time_info->user.stop-time_info->user.start;
134  time_info->elapsed.total-=time_info->elapsed.stop-
135  time_info->elapsed.start;
136  }
137  time_info->state=RunningTimerState;
138  return(MagickTrue);
139 }
140 
141 /*
142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 % %
144 % %
145 % %
146 % D e s t r o y T i m e r I n f o %
147 % %
148 % %
149 % %
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 %
152 % DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
153 %
154 % The format of the DestroyTimerInfo method is:
155 %
156 % TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
157 %
158 % A description of each parameter follows:
159 %
160 % o timer_info: The cipher context.
161 %
162 */
164 {
165  assert(timer_info != (TimerInfo *) NULL);
166  assert(timer_info->signature == MagickCoreSignature);
167  timer_info->signature=(~MagickCoreSignature);
168  timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
169  return(timer_info);
170 }
171 
172 /*
173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 % %
175 % %
176 % %
177 + E l a p s e d T i m e %
178 % %
179 % %
180 % %
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 %
183 % ElapsedTime() returns the elapsed time (in seconds) since the last call to
184 % StartTimer().
185 %
186 % The format of the ElapsedTime method is:
187 %
188 % double ElapsedTime()
189 %
190 */
191 static double ElapsedTime(void)
192 {
193 #if defined(MAGICKCORE_HAVE_CLOCK_GETTIME)
194 #define NANOSECONDS_PER_SECOND 1000000000.0
195 #if defined(CLOCK_HIGHRES)
196 # define CLOCK_ID CLOCK_HIGHRES
197 #elif defined(CLOCK_MONOTONIC_RAW)
198 # define CLOCK_ID CLOCK_MONOTONIC_RAW
199 #elif defined(CLOCK_MONOTONIC_PRECISE)
200 # define CLOCK_ID CLOCK_MONOTONIC_PRECISE
201 #elif defined(CLOCK_MONOTONIC)
202 # define CLOCK_ID CLOCK_MONOTONIC
203 #else
204 # define CLOCK_ID CLOCK_REALTIME
205 #endif
206 
207  struct timespec
208  timer;
209 
210  (void) clock_gettime(CLOCK_ID,&timer);
211  return((double) timer.tv_sec+timer.tv_nsec/NANOSECONDS_PER_SECOND);
212 #elif defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
213  struct tms
214  timer;
215 
216  return((double) times(&timer)/sysconf(_SC_CLK_TCK));
217 #else
218 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
219  return(NTElapsedTime());
220 #else
221  return((double) clock()/CLOCKS_PER_SEC);
222 #endif
223 #endif
224 }
225 
226 /*
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 % %
229 % %
230 % %
231 % F o r m a t M a g i c k T i m e %
232 % %
233 % %
234 % %
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 %
237 % FormatMagickTime() returns the specified time in the Internet date/time
238 % format and the length of the timestamp.
239 %
240 % The format of the FormatMagickTime method is:
241 %
242 % ssize_t FormatMagickTime(const time_t time,const size_t length,
243 % char *timestamp)
244 %
245 % A description of each parameter follows.
246 %
247 % o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
248 % measured in seconds.
249 %
250 % o length: the maximum length of the string.
251 %
252 % o timestamp: Return the Internet date/time here.
253 %
254 */
255 MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
256  char *timestamp)
257 {
258  ssize_t
259  count;
260 
261  struct tm
262  gm_time;
263 
264  assert(timestamp != (char *) NULL);
265  GetMagickUTCtime(&time,&gm_time);
266  count=FormatLocaleString(timestamp,length,
267  "%04d-%02d-%02dT%02d:%02d:%02d%+03d:00",gm_time.tm_year+1900,
268  gm_time.tm_mon+1,gm_time.tm_mday,gm_time.tm_hour,gm_time.tm_min,
269  gm_time.tm_sec,0);
270  return(count);
271 }
272 
273 /*
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 % %
276 % %
277 % %
278 % G e t E l a p s e d T i m e %
279 % %
280 % %
281 % %
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 %
284 % GetElapsedTime() returns the elapsed time (in seconds) passed between the
285 % start and stop events. If the stopwatch is still running, it is stopped
286 % first.
287 %
288 % The format of the GetElapsedTime method is:
289 %
290 % double GetElapsedTime(TimerInfo *time_info)
291 %
292 % A description of each parameter follows.
293 %
294 % o time_info: Timer statistics structure.
295 %
296 */
298 {
299  assert(time_info != (TimerInfo *) NULL);
300  assert(time_info->signature == MagickCoreSignature);
301  if (time_info->state == UndefinedTimerState)
302  return(0.0);
303  if (time_info->state == RunningTimerState)
304  StopTimer(time_info);
305  return(time_info->elapsed.total);
306 }
307 
308 /*
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310 % %
311 % %
312 % %
313 + G e t M a g i c k T i m e %
314 % %
315 % %
316 % %
317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 %
319 % GetMagickTime() returns the time as the number of seconds since the Epoch.
320 %
321 % The format of the GetElapsedTime method is:
322 %
323 % time_t GetElapsedTime(void)
324 %
325 */
327 {
328  char
329  *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
330 
331  if (source_date_epoch != (char *) NULL)
332  {
333  time_t
334  epoch;
335 
336  epoch=(time_t) StringToDouble(source_date_epoch,(char **) NULL);
337  if ((epoch > 0) && (epoch <= time((time_t *) NULL)))
338  return(epoch);
339  }
340  return(time((time_t *) NULL));
341 }
342 
343 /*
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 % %
346 % %
347 % %
348 + G e t T i m e r I n f o %
349 % %
350 % %
351 % %
352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 %
354 % GetTimerInfo() initializes the TimerInfo structure.
355 %
356 % The format of the GetTimerInfo method is:
357 %
358 % void GetTimerInfo(TimerInfo *time_info)
359 %
360 % A description of each parameter follows.
361 %
362 % o time_info: Timer statistics structure.
363 %
364 */
366 {
367  /*
368  Create a stopwatch and start it.
369  */
370  assert(time_info != (TimerInfo *) NULL);
371  (void) memset(time_info,0,sizeof(*time_info));
372  time_info->state=UndefinedTimerState;
373  time_info->signature=MagickCoreSignature;
374  StartTimer(time_info,MagickTrue);
375 }
376 
377 /*
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 % %
380 % %
381 % %
382 % G e t U s e r T i m e %
383 % %
384 % %
385 % %
386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 %
388 % GetUserTime() returns the User time (user and system) by the operating
389 % system (in seconds) between the start and stop events. If the stopwatch is
390 % still running, it is stopped first.
391 %
392 % The format of the GetUserTime method is:
393 %
394 % double GetUserTime(TimerInfo *time_info)
395 %
396 % A description of each parameter follows.
397 %
398 % o time_info: Timer statistics structure.
399 %
400 */
402 {
403  assert(time_info != (TimerInfo *) NULL);
404  assert(time_info->signature == MagickCoreSignature);
405  if (time_info->state == UndefinedTimerState)
406  return(0.0);
407  if (time_info->state == RunningTimerState)
408  StopTimer(time_info);
409  return(time_info->user.total);
410 }
411 
412 /*
413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
414 % %
415 % %
416 % %
417 % R e s e t T i m e r %
418 % %
419 % %
420 % %
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422 %
423 % ResetTimer() resets the stopwatch.
424 %
425 % The format of the ResetTimer method is:
426 %
427 % void ResetTimer(TimerInfo *time_info)
428 %
429 % A description of each parameter follows.
430 %
431 % o time_info: Timer statistics structure.
432 %
433 */
435 {
436  assert(time_info != (TimerInfo *) NULL);
437  assert(time_info->signature == MagickCoreSignature);
438  StopTimer(time_info);
439  time_info->elapsed.stop=0.0;
440  time_info->user.stop=0.0;
441 }
442 
443 /*
444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445 % %
446 % %
447 % %
448 + S t a r t T i m e r %
449 % %
450 % %
451 % %
452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453 %
454 % StartTimer() starts the stopwatch.
455 %
456 % The format of the StartTimer method is:
457 %
458 % void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
459 %
460 % A description of each parameter follows.
461 %
462 % o time_info: Timer statistics structure.
463 %
464 % o reset: If reset is MagickTrue, then the stopwatch is reset prior to
465 % starting. If reset is MagickFalse, then timing is continued without
466 % resetting the stopwatch.
467 %
468 */
470 {
471  assert(time_info != (TimerInfo *) NULL);
472  assert(time_info->signature == MagickCoreSignature);
473  if (reset != MagickFalse)
474  {
475  /*
476  Reset the stopwatch before starting it.
477  */
478  time_info->user.total=0.0;
479  time_info->elapsed.total=0.0;
480  }
481  if (time_info->state != RunningTimerState)
482  {
483  time_info->elapsed.start=ElapsedTime();
484  time_info->user.start=UserTime();
485  }
486  time_info->state=RunningTimerState;
487 }
488 
489 /*
490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % %
492 % %
493 % %
494 + S t o p T i m e r %
495 % %
496 % %
497 % %
498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 %
500 % StopTimer() stops the stopwatch.
501 %
502 % The format of the StopTimer method is:
503 %
504 % void StopTimer(TimerInfo *time_info)
505 %
506 % A description of each parameter follows.
507 %
508 % o time_info: Timer statistics structure.
509 %
510 */
511 static void StopTimer(TimerInfo *time_info)
512 {
513  assert(time_info != (TimerInfo *) NULL);
514  assert(time_info->signature == MagickCoreSignature);
515  time_info->elapsed.stop=ElapsedTime();
516  time_info->user.stop=UserTime();
517  if (time_info->state == RunningTimerState)
518  {
519  time_info->user.total+=time_info->user.stop-
520  time_info->user.start+MagickEpsilon;
521  time_info->elapsed.total+=time_info->elapsed.stop-
522  time_info->elapsed.start+MagickEpsilon;
523  }
524  time_info->state=StoppedTimerState;
525 }
526 
527 /*
528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
529 % %
530 % %
531 % %
532 + U s e r T i m e %
533 % %
534 % %
535 % %
536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
537 %
538 % UserTime() returns the total time the process has been scheduled (in
539 % seconds) since the last call to StartTimer().
540 %
541 % The format of the UserTime method is:
542 %
543 % double UserTime()
544 %
545 */
546 static double UserTime(void)
547 {
548 #if defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
549  struct tms
550  timer;
551 
552  (void) times(&timer);
553  return((double) (timer.tms_utime+timer.tms_stime)/sysconf(_SC_CLK_TCK));
554 #else
555 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
556  return(NTUserTime());
557 #else
558  return((double) clock()/CLOCKS_PER_SEC);
559 #endif
560 #endif
561 }
MagickExport double GetUserTime(TimerInfo *time_info)
Definition: timer.c:401
double stop
Definition: timer.h:35
static double ElapsedTime(void)
Definition: timer.c:191
size_t signature
Definition: timer.h:50
MagickExport TimerInfo * DestroyTimerInfo(TimerInfo *timer_info)
Definition: timer.c:163
MagickExport TimerInfo * AcquireTimerInfo(void)
Definition: timer.c:90
static double StringToDouble(const char *magick_restrict string, char **magick_restrict sentinal)
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:499
static void * AcquireCriticalMemory(const size_t size)
double total
Definition: timer.h:35
MagickExport void StartTimer(TimerInfo *time_info, const MagickBooleanType reset)
Definition: timer.c:469
static double UserTime(void)
Definition: timer.c:546
#define MagickEpsilon
Definition: magick-type.h:110
#define MagickCoreSignature
MagickBooleanType
Definition: magick-type.h:158
Timer user
Definition: timer.h:43
MagickExport time_t GetMagickTime(void)
Definition: timer.c:326
static void GetMagickUTCtime(const time_t *timep, struct tm *result)
Definition: timer-private.h:25
MagickExport void ResetTimer(TimerInfo *time_info)
Definition: timer.c:434
MagickExport void GetTimerInfo(TimerInfo *time_info)
Definition: timer.c:365
MagickExport double GetElapsedTime(TimerInfo *time_info)
Definition: timer.c:297
Timer elapsed
Definition: timer.h:43
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1069
#define CLOCKS_PER_SEC
Definition: timer.c:59
#define MagickExport
static void StopTimer(TimerInfo *)
Definition: timer.c:511
double start
Definition: timer.h:35
MagickExport ssize_t FormatMagickTime(const time_t time, const size_t length, char *timestamp)
Definition: timer.c:255
TimerState state
Definition: timer.h:47
MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
Definition: timer.c:125