-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0350eba
commit 3395443
Showing
2 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <math.h> | ||
|
||
|
||
// | ||
// '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); | ||
} |