libroot: Use timespec_to_bigtime and bigtime_to_timespec in more places.

Two minor behavioral changes: EINVAL is now returned on invalid
times in more places, and clock_settime now rounds up instead of down.
Otherwise all should be as before.
This commit is contained in:
Augustin Cavalier 2024-11-08 13:41:36 -05:00
parent 7c5e909fba
commit b8fdef84a6
5 changed files with 27 additions and 35 deletions

View File

@ -15,6 +15,7 @@
#include <syscalls.h>
#include <user_mutex_defs.h>
#include <time_private.h>
#define MUTEX_TYPE_BITS 0x0000000f
@ -118,13 +119,9 @@ int
pthread_mutex_clocklock(pthread_mutex_t* mutex, clockid_t clock_id,
const struct timespec* abstime)
{
// translate the timeout
bool invalidTime = false;
bigtime_t timeout = 0;
if (abstime != NULL && abstime->tv_nsec < 1000 * 1000 * 1000
&& abstime->tv_nsec >= 0) {
timeout = abstime->tv_sec * 1000000LL + abstime->tv_nsec / 1000LL;
} else
bool invalidTime = false;
if (abstime == NULL || !timespec_to_bigtime(*abstime, timeout))
invalidTime = true;
uint32 flags = 0;

View File

@ -12,6 +12,7 @@
#include <AutoLocker.h>
#include <syscalls.h>
#include <time_private.h>
#include <user_mutex_defs.h>
#include <user_thread.h>
#include <util/DoublyLinkedList.h>
@ -352,10 +353,12 @@ pthread_rwlock_tryrdlock(pthread_rwlock_t* lock)
int
pthread_rwlock_clockrdlock(pthread_rwlock_t* lock, clockid_t clock_id,
const struct timespec *abstime)
const struct timespec *abstime)
{
bigtime_t timeout = abstime->tv_sec * 1000000LL
+ abstime->tv_nsec / 1000LL;
bigtime_t timeout;
if (abstime == NULL || !timespec_to_bigtime(*abstime, timeout))
return EINVAL;
uint32 flags = 0;
if (timeout >= 0) {
switch (clock_id) {
@ -412,11 +415,13 @@ pthread_rwlock_trywrlock(pthread_rwlock_t* lock)
int
pthread_rwlock_clockwrlock (pthread_rwlock_t* lock, clockid_t clock_id,
pthread_rwlock_clockwrlock(pthread_rwlock_t* lock, clockid_t clock_id,
const struct timespec *abstime)
{
bigtime_t timeout = abstime->tv_sec * 1000000LL
+ abstime->tv_nsec / 1000LL;
bigtime_t timeout;
if (abstime == NULL || !timespec_to_bigtime(*abstime, timeout))
return EINVAL;
uint32 flags = 0;
if (timeout >= 0) {
switch (clock_id) {
@ -510,4 +515,3 @@ pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _attr, int shared)
return 0;
}

View File

@ -12,6 +12,7 @@
#include <syscall_utils.h>
#include <errno_private.h>
#include <time_private.h>
#include <syscalls.h>
@ -28,10 +29,11 @@ sigtimedwait(const sigset_t* set, siginfo_t* info,
uint32 flags;
bigtime_t timeoutMicros;
if (timeout != NULL) {
timeoutMicros = system_time();
if (!timespec_to_bigtime(*timeout, timeoutMicros))
RETURN_AND_SET_ERRNO(EINVAL);
timeoutMicros += system_time();
flags = B_ABSOLUTE_TIMEOUT;
timeoutMicros += (bigtime_t)timeout->tv_sec * 1000000
+ timeout->tv_nsec / 1000;
} else {
flags = 0;
timeoutMicros = 0;

View File

@ -55,9 +55,7 @@ clock_getres(clockid_t clockID, struct timespec* resolution)
int
clock_gettime(clockid_t clockID, struct timespec* time)
{
// get the time in microseconds
bigtime_t microSeconds;
switch (clockID) {
case CLOCK_MONOTONIC:
microSeconds = system_time();
@ -75,10 +73,7 @@ clock_gettime(clockid_t clockID, struct timespec* time)
}
}
// set the result
time->tv_sec = microSeconds / 1000000;
time->tv_nsec = (microSeconds % 1000000) * 1000;
bigtime_to_timespec(microSeconds, *time);
return 0;
}
@ -90,14 +85,10 @@ clock_settime(clockid_t clockID, const struct timespec* time)
if (clockID == CLOCK_MONOTONIC)
RETURN_AND_SET_ERRNO(EINVAL);
// check timespec validity
if (time->tv_sec < 0 || time->tv_nsec < 0 || time->tv_nsec >= 1000000000)
bigtime_t microSeconds;
if (!timespec_to_bigtime(*time, microSeconds))
RETURN_AND_SET_ERRNO(EINVAL);
// convert to microseconds and set the clock
bigtime_t microSeconds = (bigtime_t)time->tv_sec * 1000000
+ time->tv_nsec / 1000;
RETURN_AND_SET_ERRNO(_kern_set_clock(clockID, microSeconds));
}
@ -130,8 +121,7 @@ clock_nanosleep(clockid_t clockID, int flags, const struct timespec* time,
// remaining wait time.
if (error == B_INTERRUPTED && remainingTime != NULL) {
if (remainingMicroSeconds > 0) {
remainingTime->tv_sec = remainingMicroSeconds / 1000000;
remainingTime->tv_nsec = (remainingMicroSeconds % 1000000) * 1000;
bigtime_to_timespec(remainingMicroSeconds, *remainingTime);
} else {
// We were slow enough that the wait time passed anyway.
error = B_OK;

View File

@ -9,17 +9,16 @@
#include <OS.h>
#include <SupportDefs.h>
#include <time_private.h>
int
timespec_get(struct timespec* time, int base)
{
if (base != TIME_UTC)
return 0;
bigtime_t microSeconds = real_time_clock_usecs();
// set the result
time->tv_sec = microSeconds / 1000000;
time->tv_nsec = (microSeconds % 1000000) * 1000;
bigtime_t microSeconds = real_time_clock_usecs();
bigtime_to_timespec(microSeconds, *time);
return base;
}