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
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)
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;
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#if defined(MAGICKCORE_HAVE_CLOCK_GETTIME)
209#define NANOSECONDS_PER_SECOND 1000000000.0
210#if defined(CLOCK_HIGHRES)
211# define CLOCK_ID CLOCK_HIGHRES
212#elif defined(CLOCK_MONOTONIC_RAW)
213# define CLOCK_ID CLOCK_MONOTONIC_RAW
214#elif defined(CLOCK_MONOTONIC_PRECISE)
215# define CLOCK_ID CLOCK_MONOTONIC_PRECISE
216#elif defined(CLOCK_MONOTONIC)
217# define CLOCK_ID CLOCK_MONOTONIC
219# define CLOCK_ID CLOCK_REALTIME
225 (void) clock_gettime(CLOCK_ID,&timer);
226 return((
double) timer.tv_sec+timer.tv_nsec/NANOSECONDS_PER_SECOND);
227#elif defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
231 return((
double) times(&timer)/sysconf(_SC_CLK_TCK));
233#if defined(MAGICKCORE_WINDOWS_SUPPORT)
234 return(NTElapsedTime());
236 return((
double) clock()/CLOCKS_PER_SEC);
270MagickExport ssize_t FormatMagickTime(
const time_t time,
const size_t length,
279 assert(timestamp != (
char *) NULL);
280 if (date_precision == -1)
286 limit=GetEnvironmentValue(
"MAGICK_DATE_PRECISION");
287 if (limit != (
char *) NULL)
289 date_precision=StringToInteger(limit);
290 limit=DestroyString(limit);
293 GetMagickUTCTime(&time,&utc_time);
294 count=FormatLocaleString(timestamp,length,
295 "%04d-%02d-%02dT%02d:%02d:%02d%+03d:00",utc_time.tm_year+1900,
296 utc_time.tm_mon+1,utc_time.tm_mday,utc_time.tm_hour,utc_time.tm_min,
298 if ((date_precision > 0) && (date_precision < (ssize_t) strlen(timestamp)))
299 timestamp[date_precision]=
'\0';
327MagickExport
double GetElapsedTime(
TimerInfo *time_info)
330 assert(time_info->signature == MagickCoreSignature);
331 if (time_info->state == UndefinedTimerState)
333 if (time_info->state == RunningTimerState)
334 StopTimer(time_info);
335 return(time_info->elapsed.total);
356static void InitializeEpoch(
void)
358 if (epoch_initialized == MagickFalse)
363 source_date_epoch=GetEnvironmentValue(
"SOURCE_DATE_EPOCH");
364 if (source_date_epoch != (
const char *) NULL)
369 epoch=(time_t) StringToMagickOffsetType(source_date_epoch,100.0);
370 if ((epoch > 0) && (epoch <= time((time_t *) NULL)))
372 source_date_epoch=DestroyString(source_date_epoch);
374 epoch_initialized=MagickTrue;
378MagickExport time_t GetMagickTime(
void)
381 if (magick_epoch != 0)
382 return(magick_epoch);
383 return(time((time_t *) NULL));
408MagickExport
void GetTimerInfo(
TimerInfo *time_info)
414 (void) memset(time_info,0,
sizeof(*time_info));
415 time_info->state=UndefinedTimerState;
416 time_info->signature=MagickCoreSignature;
417 StartTimer(time_info,MagickTrue);
444MagickExport
double GetUserTime(
TimerInfo *time_info)
447 assert(time_info->signature == MagickCoreSignature);
448 if (time_info->state == UndefinedTimerState)
450 if (time_info->state == RunningTimerState)
451 StopTimer(time_info);
452 return(time_info->user.total);
476MagickExport MagickBooleanType IsSourceDataEpochSet(
void)
479 return(magick_epoch != 0 ? MagickTrue : MagickFalse);
504MagickExport
void ResetTimer(
TimerInfo *time_info)
507 assert(time_info->signature == MagickCoreSignature);
508 StopTimer(time_info);
509 time_info->elapsed.stop=0.0;
510 time_info->user.stop=0.0;
535MagickPrivate
void SetMagickDatePrecision(
const unsigned long precision)
537 date_precision=(ssize_t) precision;
566MagickExport
void StartTimer(
TimerInfo *time_info,
const MagickBooleanType reset)
569 assert(time_info->signature == MagickCoreSignature);
570 if (reset != MagickFalse)
575 time_info->user.total=0.0;
576 time_info->elapsed.total=0.0;
578 if (time_info->state != RunningTimerState)
580 time_info->elapsed.start=ElapsedTime();
581 time_info->user.start=UserTime();
583 time_info->state=RunningTimerState;
608static void StopTimer(
TimerInfo *time_info)
611 assert(time_info->signature == MagickCoreSignature);
612 time_info->elapsed.stop=ElapsedTime();
613 time_info->user.stop=UserTime();
614 if (time_info->state == RunningTimerState)
616 time_info->user.total+=time_info->user.stop-
617 time_info->user.start+MagickEpsilon;
618 time_info->elapsed.total+=time_info->elapsed.stop-
619 time_info->elapsed.start+MagickEpsilon;
621 time_info->state=StoppedTimerState;
643static double UserTime(
void)
645#if defined(MAGICKCORE_HAVE_TIMES) && defined(MAGICKCORE_HAVE_SYSCONF)
649 (void) times(&timer);
650 return((
double) (timer.tms_utime+timer.tms_stime)/sysconf(_SC_CLK_TCK));
652#if defined(MAGICKCORE_WINDOWS_SUPPORT)
653 return(NTElapsedTime());
655 return((
double) clock()/CLOCKS_PER_SEC);