MagickCore  7.0.10
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-2020 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  utc_time;
263 
264  assert(timestamp != (char *) NULL);
265  GetMagickUTCtime(&time,&utc_time);
266  count=FormatLocaleString(timestamp,length,
267  "%04d-%02d-%02dT%02d:%02d:%02d%+03d:00",utc_time.tm_year+1900,
268  utc_time.tm_mon+1,utc_time.tm_mday,utc_time.tm_hour,utc_time.tm_min,
269  utc_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  static const char
329  *source_date_epoch = (const char *) NULL;
330 
331  static MagickBooleanType
332  epoch_initalized = MagickFalse;
333 
334  if (epoch_initalized == MagickFalse)
335  {
336  source_date_epoch=getenv("SOURCE_DATE_EPOCH");
337  epoch_initalized=MagickTrue;
338  }
339  if (source_date_epoch != (const char *) NULL)
340  {
341  time_t
342  epoch;
343 
344  epoch=(time_t) StringToDouble(source_date_epoch,(char **) NULL);
345  if ((epoch > 0) && (epoch <= time((time_t *) NULL)))
346  return(epoch);
347  }
348  return(time((time_t *) NULL));
349 }
350 
351 /*
352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 % %
354 % %
355 % %
356 + G e t T i m e r I n f o %
357 % %
358 % %
359 % %
360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 %
362 % GetTimerInfo() initializes the TimerInfo structure.
363 %
364 % The format of the GetTimerInfo method is:
365 %
366 % void GetTimerInfo(TimerInfo *time_info)
367 %
368 % A description of each parameter follows.
369 %
370 % o time_info: Timer statistics structure.
371 %
372 */
374 {
375  /*
376  Create a stopwatch and start it.
377  */
378  assert(time_info != (TimerInfo *) NULL);
379  (void) memset(time_info,0,sizeof(*time_info));
380  time_info->state=UndefinedTimerState;
381  time_info->signature=MagickCoreSignature;
382  StartTimer(time_info,MagickTrue);
383 }
384 
385 /*
386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 % %
388 % %
389 % %
390 % G e t U s e r T i m e %
391 % %
392 % %
393 % %
394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 %
396 % GetUserTime() returns the User time (user and system) by the operating
397 % system (in seconds) between the start and stop events. If the stopwatch is
398 % still running, it is stopped first.
399 %
400 % The format of the GetUserTime method is:
401 %
402 % double GetUserTime(TimerInfo *time_info)
403 %
404 % A description of each parameter follows.
405 %
406 % o time_info: Timer statistics structure.
407 %
408 */
410 {
411  assert(time_info != (TimerInfo *) NULL);
412  assert(time_info->signature == MagickCoreSignature);
413  if (time_info->state == UndefinedTimerState)
414  return(0.0);
415  if (time_info->state == RunningTimerState)
416  StopTimer(time_info);
417  return(time_info->user.total);
418 }
419 
420 /*
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422 % %
423 % %
424 % %
425 % R e s e t T i m e r %
426 % %
427 % %
428 % %
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 %
431 % ResetTimer() resets the stopwatch.
432 %
433 % The format of the ResetTimer method is:
434 %
435 % void ResetTimer(TimerInfo *time_info)
436 %
437 % A description of each parameter follows.
438 %
439 % o time_info: Timer statistics structure.
440 %
441 */
443 {
444  assert(time_info != (TimerInfo *) NULL);
445  assert(time_info->signature == MagickCoreSignature);
446  StopTimer(time_info);
447  time_info->elapsed.stop=0.0;
448  time_info->user.stop=0.0;
449 }
450 
451 /*
452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453 % %
454 % %
455 % %
456 + S t a r t T i m e r %
457 % %
458 % %
459 % %
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461 %
462 % StartTimer() starts the stopwatch.
463 %
464 % The format of the StartTimer method is:
465 %
466 % void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
467 %
468 % A description of each parameter follows.
469 %
470 % o time_info: Timer statistics structure.
471 %
472 % o reset: If reset is MagickTrue, then the stopwatch is reset prior to
473 % starting. If reset is MagickFalse, then timing is continued without
474 % resetting the stopwatch.
475 %
476 */
478 {
479  assert(time_info != (TimerInfo *) NULL);
480  assert(time_info->signature == MagickCoreSignature);
481  if (reset != MagickFalse)
482  {
483  /*
484  Reset the stopwatch before starting it.
485  */
486  time_info->user.total=0.0;
487  time_info->elapsed.total=0.0;
488  }
489  if (time_info->state != RunningTimerState)
490  {
491  time_info->elapsed.start=ElapsedTime();
492  time_info->user.start=UserTime();
493  }
494  time_info->state=RunningTimerState;
495 }
496 
497 /*
498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % %
500 % %
501 % %
502 + S t o p T i m e r %
503 % %
504 % %
505 % %
506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
507 %
508 % StopTimer() stops the stopwatch.
509 %
510 % The format of the StopTimer method is:
511 %
512 % void StopTimer(TimerInfo *time_info)
513 %
514 % A description of each parameter follows.
515 %
516 % o time_info: Timer statistics structure.
517 %
518 */
519 static void StopTimer(TimerInfo *time_info)
520 {
521  assert(time_info != (TimerInfo *) NULL);
522  assert(time_info->signature == MagickCoreSignature);
523  time_info->elapsed.stop=ElapsedTime();
524  time_info->user.stop=UserTime();
525  if (time_info->state == RunningTimerState)
526  {
527  time_info->user.total+=time_info->user.stop-
528  time_info->user.start+MagickEpsilon;
529  time_info->elapsed.total+=time_info->elapsed.stop-
530  time_info->elapsed.start+MagickEpsilon;
531  }
532  time_info->state=StoppedTimerState;
533 }
534 
535 /*
536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
537 % %
538 % %
539 % %
540 + U s e r T i m e %
541 % %
542 % %
543 % %
544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 %
546 % UserTime() returns the total time the process has been scheduled (in
547 % seconds) since the last call to StartTimer().
548 %
549 % The format of the UserTime method is:
550 %
551 % double UserTime()
552 %
553 */
554 static double UserTime(void)
555 {
556 #if defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
557  struct tms
558  timer;
559 
560  (void) times(&timer);
561  return((double) (timer.tms_utime+timer.tms_stime)/sysconf(_SC_CLK_TCK));
562 #else
563 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
564  return(NTUserTime());
565 #else
566  return((double) clock()/CLOCKS_PER_SEC);
567 #endif
568 #endif
569 }
MagickExport double GetUserTime(TimerInfo *time_info)
Definition: timer.c:409
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
double total
Definition: timer.h:35
MagickExport void StartTimer(TimerInfo *time_info, const MagickBooleanType reset)
Definition: timer.c:477
static double UserTime(void)
Definition: timer.c:554
#define MagickEpsilon
Definition: magick-type.h:114
#define MagickCoreSignature
MagickBooleanType
Definition: magick-type.h:169
Timer user
Definition: timer.h:43
MagickExport void * AcquireCriticalMemory(const size_t size)
Definition: memory.c:595
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:442
MagickExport void GetTimerInfo(TimerInfo *time_info)
Definition: timer.c:373
MagickExport double GetElapsedTime(TimerInfo *time_info)
Definition: timer.c:297
Timer elapsed
Definition: timer.h:43
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1123
#define CLOCKS_PER_SEC
Definition: timer.c:59
#define MagickExport
static void StopTimer(TimerInfo *)
Definition: timer.c:519
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