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"
61#if !defined(CLOCKS_PER_SEC)
62#define CLOCKS_PER_SEC 100
72 StopTimer(TimerInfo *);
81 magick_epoch = (time_t) 0;
83static MagickBooleanType
84 epoch_initialized = MagickFalse;
105MagickExport TimerInfo *AcquireTimerInfo(
void)
110 timer_info=(TimerInfo *) AcquireCriticalMemory(
sizeof(*timer_info));
111 (void) memset(timer_info,0,
sizeof(*timer_info));
112 timer_info->signature=MagickCoreSignature;
113 GetTimerInfo(timer_info);
140MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
142 assert(time_info != (TimerInfo *) NULL);
143 assert(time_info->signature == MagickCoreSignature);
144 if (time_info->state == UndefinedTimerState)
146 if (time_info->state == StoppedTimerState)
148 time_info->user.total-=time_info->user.stop-time_info->user.start;
149 time_info->elapsed.total-=time_info->elapsed.stop-
150 time_info->elapsed.start;
152 time_info->state=RunningTimerState;
178MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
180 assert(timer_info != (TimerInfo *) NULL);
181 assert(timer_info->signature == MagickCoreSignature);
182 timer_info->signature=(~MagickCoreSignature);
183 timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
206static double ElapsedTime(
void)
208#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
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
221# define CLOCK_ID CLOCK_REALTIME
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)
233 return((
double) times(&timer)/sysconf(_SC_CLK_TCK));
235#if defined(MAGICKCORE_WINDOWS_SUPPORT)
236 return(NTElapsedTime());
238 return((
double) clock()/CLOCKS_PER_SEC);
272MagickExport ssize_t FormatMagickTime(
const time_t time,
const size_t length,
281 assert(timestamp != (
char *) NULL);
282 if (date_precision == -1)
288 limit=GetEnvironmentValue(
"MAGICK_DATE_PRECISION");
289 if (limit != (
char *) NULL)
291 date_precision=StringToInteger(limit);
292 limit=DestroyString(limit);
295 GetMagickUTCTime(&time,&utc_time);
296 count=FormatLocaleString(timestamp,length,
297 "%04d-%02d-%02dT%02d:%02d:%02d%+03d:00",utc_time.tm_year+1900,
298 utc_time.tm_mon+1,utc_time.tm_mday,utc_time.tm_hour,utc_time.tm_min,
300 if ((date_precision > 0) && (date_precision < (ssize_t) strlen(timestamp)))
301 timestamp[date_precision]=
'\0';
329MagickExport
double GetElapsedTime(TimerInfo *time_info)
331 assert(time_info != (TimerInfo *) NULL);
332 assert(time_info->signature == MagickCoreSignature);
333 if (time_info->state == UndefinedTimerState)
335 if (time_info->state == RunningTimerState)
336 StopTimer(time_info);
337 return(time_info->elapsed.total);
358static void InitializeEpoch(
void)
360 if (epoch_initialized == MagickFalse)
365 source_date_epoch=GetEnvironmentValue(
"SOURCE_DATE_EPOCH");
366 if (source_date_epoch != (
const char *) NULL)
371 epoch=(time_t) StringToMagickOffsetType(source_date_epoch,100.0);
372 if ((epoch > 0) && (epoch <= time((time_t *) NULL)))
374 source_date_epoch=DestroyString(source_date_epoch);
376 epoch_initialized=MagickTrue;
380MagickExport time_t GetMagickTime(
void)
382#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
383 return((time_t) 1234567890);
386 if (magick_epoch != 0)
387 return(magick_epoch);
388 return(time((time_t *) NULL));
414MagickExport
void GetTimerInfo(TimerInfo *time_info)
419 assert(time_info != (TimerInfo *) NULL);
420 (void) memset(time_info,0,
sizeof(*time_info));
421 time_info->state=UndefinedTimerState;
422 time_info->signature=MagickCoreSignature;
423 StartTimer(time_info,MagickTrue);
450MagickExport
double GetUserTime(TimerInfo *time_info)
452 assert(time_info != (TimerInfo *) NULL);
453 assert(time_info->signature == MagickCoreSignature);
454 if (time_info->state == UndefinedTimerState)
456 if (time_info->state == RunningTimerState)
457 StopTimer(time_info);
458 return(time_info->user.total);
482MagickExport MagickBooleanType IsSourceDataEpochSet(
void)
485 return(magick_epoch != 0 ? MagickTrue : MagickFalse);
510MagickExport
void ResetTimer(TimerInfo *time_info)
512 assert(time_info != (TimerInfo *) NULL);
513 assert(time_info->signature == MagickCoreSignature);
514 StopTimer(time_info);
515 time_info->elapsed.stop=0.0;
516 time_info->user.stop=0.0;
541MagickPrivate
void SetMagickDatePrecision(
const unsigned long precision)
543 date_precision=(ssize_t) precision;
572MagickExport
void StartTimer(TimerInfo *time_info,
const MagickBooleanType reset)
574 assert(time_info != (TimerInfo *) NULL);
575 assert(time_info->signature == MagickCoreSignature);
576 if (reset != MagickFalse)
581 time_info->user.total=0.0;
582 time_info->elapsed.total=0.0;
584 if (time_info->state != RunningTimerState)
586 time_info->elapsed.start=ElapsedTime();
587 time_info->user.start=UserTime();
589 time_info->state=RunningTimerState;
614static void StopTimer(TimerInfo *time_info)
616 assert(time_info != (TimerInfo *) NULL);
617 assert(time_info->signature == MagickCoreSignature);
618 time_info->elapsed.stop=ElapsedTime();
619 time_info->user.stop=UserTime();
620 if (time_info->state == RunningTimerState)
622 time_info->user.total+=time_info->user.stop-
623 time_info->user.start+MagickEpsilon;
624 time_info->elapsed.total+=time_info->elapsed.stop-
625 time_info->elapsed.start+MagickEpsilon;
627 time_info->state=StoppedTimerState;
649static double UserTime(
void)
651#if defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
655 (void) times(&timer);
656 return((
double) (timer.tms_utime+timer.tms_stime)/sysconf(_SC_CLK_TCK));
658#if defined(MAGICKCORE_WINDOWS_SUPPORT)
659 return(NTElapsedTime());
661 return((
double) clock()/CLOCKS_PER_SEC);