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