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