From: Michael R Sweet Date: Tue, 22 Oct 2024 20:25:50 +0000 (-0400) Subject: Add cupsGetClock API. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=339544359fcc37e6f964a2bcf826d5990d04606a;p=thirdparty%2Fcups.git Add cupsGetClock API. --- diff --git a/cups/clock.c b/cups/clock.c new file mode 100644 index 0000000000..51bb64b3d6 --- /dev/null +++ b/cups/clock.c @@ -0,0 +1,112 @@ +// +// Monotonic clock API for CUPS. +// +// Copyright © 2024 by OpenPrinting. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#include "cups-private.h" + + +// +// Local globals... +// + +static bool cups_clock_init = false;// Clock initialized? +static cups_mutex_t cups_clock_mutex = CUPS_MUTEX_INITIALIZER; + // Mutex to control access +#ifdef _WIN32 +static ULONGLONG cups_first_tick; // First tick count +#else +# ifdef CLOCK_MONOTONIC +static struct timespec cups_first_clock;// First clock value +# endif // CLOCK_MONOTONIC +static struct timeval cups_first_time; // First time value +#endif // _WIN32 + + +// +// 'cupsGetClock()' - Get a monotonic clock value in seconds. +// +// This function returns a monotonically increasing clock value in seconds. The +// first call will always return 0.0. Subsequent calls will return the number +// of seconds that have elapsed since the first call, regardless of system time +// changes, sleep, etc. The sub-second accuracy varies based on the operating +// system and hardware but is typically 10ms or better. +// +// @since CUPS 2.5@ +// + +double // O - Elapsed seconds +cupsGetClock(void) +{ + double secs; // Elapsed seconds +#ifdef _WIN32 + ULONGLONG curtick; // Current tick count +#else +# ifdef CLOCK_MONOTONIC + struct timespec curclock; // Current clock value +# endif // CLOCK_MONOTONIC + struct timeval curtime; // Current time value +#endif // _WIN32 + + + cupsMutexLock(&cups_clock_mutex); + +#ifdef _WIN32 + // Get the current tick count in milliseconds... + curtick = GetTickCount64(); + + if (!cups_clock_init) + { + // First time through initialize the initial tick count... + cups_clock_init = true; + cups_first_tick = curtick; + } + + // Convert ticks to seconds... + if (curtick < cups_first_tick) + secs = 0.0; + else + secs = 0.001 * (curtick - cups_first_tick); + +#else +# ifdef CLOCK_MONOTONIC + // Get the current tick count in milliseconds... + if (!clock_gettime(CLOCK_MONOTONIC, &curclock)) + { + if (!cups_clock_init) + { + // First time through initialize the initial clock value... + cups_clock_init = true; + cups_first_clock = curclock; + } + + // Convert clock value to seconds... + if ((secs = curclock.tv_sec - cups_first_clock.tv_sec + 0.000000001 * (curclock.tv_nsec - cups_first_clock.tv_nsec)) < 0.0) + secs = 0.0; + } + else +# endif // CLOCK_MONOTONIC + { + gettimeofday(&curtime, /*tzp*/NULL); + + if (!cups_clock_init) + { + // First time through initialize the initial clock value... + cups_clock_init = true; + cups_first_time = curtime; + } + + // Convert time value to seconds... + if ((secs = curtime.tv_sec - cups_first_time.tv_sec + 0.000001 * (curtime.tv_usec - cups_first_time.tv_usec)) < 0.0) + secs = 0.0; + } +#endif // _WIN32 + + cupsMutexUnlock(&cups_clock_mutex); + + return (secs); +} diff --git a/cups/testclock.c b/cups/testclock.c new file mode 100644 index 0000000000..a69ec24285 --- /dev/null +++ b/cups/testclock.c @@ -0,0 +1,88 @@ +// +// Monotonic clock test program for CUPS. +// +// Copyright © 2024 by OpenPrinting. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#include "cups.h" +#include "test-internal.h" +#include + + +// +// 'main()' - Main entry for clock tests. +// + +int // O - Exit status +main(void) +{ + double current; // Current time + + + // Test clock values at 0, 1, 5, 10, and 30 seconds + testBegin("cupsGetClock(initial)"); + current = cupsGetClock(); + if (current == 0.0) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 0.0", current); + + sleep(1); + + testBegin("cupsGetClock(1 second)"); + current = cupsGetClock(); + if (fabs(current - 1.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 1.0 +/- 0.1", current); + + sleep(4); + + testBegin("cupsGetClock(5 seconds)"); + current = cupsGetClock(); + if (fabs(current - 5.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 5.0 +/- 0.1", current); + + sleep(5); + + testBegin("cupsGetClock(10 seconds)"); + current = cupsGetClock(); + if (fabs(current - 10.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 10.0 +/- 0.1", current); + + sleep(20); + + testBegin("cupsGetClock(30 seconds)"); + current = cupsGetClock(); + if (fabs(current - 30.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 30.0 +/- 0.1", current); + + sleep(30); + + testBegin("cupsGetClock(60 seconds)"); + current = cupsGetClock(); + if (fabs(current - 60.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 60.0 +/- 0.1", current); + + sleep(60); + + testBegin("cupsGetClock(120 seconds)"); + current = cupsGetClock(); + if (fabs(current - 120.0) < 0.1) + testEndMessage(true, "%g", current); + else + testEndMessage(false, "got %g, expected 120.0 +/- 0.1", current); + + return (testsPassed ? 0 : 1); +}