posix: add timespec_is_valid() private internal function

Add a common private function timespec_is_valid() that
can be used to check if a timespec object is valid, and
use that consistently in lib/posix/options.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
This commit is contained in:
Chris Friedt 2025-04-23 08:15:17 -04:00 committed by Benjamin Cabé
commit e75f285bd1
8 changed files with 46 additions and 15 deletions

View file

@ -175,6 +175,11 @@ int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mut)
int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mut, const struct timespec *abstime)
{
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
LOG_DBG("%s is invalid", "abstime");
return EINVAL;
}
return cond_wait(cv, mut, abstime);
}

View file

@ -258,6 +258,11 @@ int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
{
mqueue_desc *mqd = (mqueue_desc *)mqdes;
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
errno = EINVAL;
return -1;
}
return send_message(mqd, msg_ptr, msg_len, K_MSEC(timespec_to_timeoutms(abstime)));
}
@ -288,6 +293,11 @@ int mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
{
mqueue_desc *mqd = (mqueue_desc *)mqdes;
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
errno = EINVAL;
return -1;
}
return receive_message(mqd, msg_ptr, msg_len, K_MSEC(timespec_to_timeoutms(abstime)));
}

View file

@ -211,6 +211,11 @@ int pthread_mutex_trylock(pthread_mutex_t *m)
int pthread_mutex_timedlock(pthread_mutex_t *m,
const struct timespec *abstime)
{
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
LOG_DBG("%s is invalid", "abstime");
return EINVAL;
}
return acquire_mutex(m, K_MSEC(timespec_to_timeoutms(abstime)));
}

View file

@ -8,9 +8,20 @@
#ifndef ZEPHYR_LIB_POSIX_POSIX_CLOCK_H_
#define ZEPHYR_LIB_POSIX_POSIX_CLOCK_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#include <zephyr/sys_clock.h>
#include <zephyr/sys/__assert.h>
static inline bool timespec_is_valid(const struct timespec *ts)
{
__ASSERT_NO_MSG(ts != NULL);
return (ts->tv_nsec >= 0) && (ts->tv_nsec < NSEC_PER_SEC);
}
uint32_t timespec_to_clock_timeoutms(clockid_t clock_id, const struct timespec *abstime);
uint32_t timespec_to_timeoutms(const struct timespec *abstime);

View file

@ -1149,11 +1149,8 @@ static int pthread_timedjoin_internal(pthread_t pthread, void **status, k_timeou
*/
int pthread_timedjoin_np(pthread_t pthread, void **status, const struct timespec *abstime)
{
if (abstime == NULL) {
return EINVAL;
}
if (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= NSEC_PER_SEC) {
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
LOG_DBG("%s is invalid", "abstime");
return EINVAL;
}

View file

@ -201,7 +201,8 @@ int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock,
uint32_t ret = 0U;
struct posix_rwlock *rwl;
if (abstime->tv_nsec < 0 || abstime->tv_nsec > NSEC_PER_SEC) {
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
LOG_DBG("%s is invalid", "abstime");
return EINVAL;
}
@ -271,7 +272,8 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock,
uint32_t ret = 0U;
struct posix_rwlock *rwl;
if (abstime->tv_nsec < 0 || abstime->tv_nsec > NSEC_PER_SEC) {
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
LOG_DBG("%s is invalid", "abstime");
return EINVAL;
}

View file

@ -5,6 +5,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "posix_clock.h"
#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/atomic.h>
@ -163,9 +165,7 @@ int sem_timedwait(sem_t *semaphore, struct timespec *abstime)
struct timespec current;
int64_t current_ms, abstime_ms;
__ASSERT(abstime, "abstime pointer NULL");
if ((abstime->tv_sec < 0) || (abstime->tv_nsec >= NSEC_PER_SEC)) {
if ((abstime == NULL) || !timespec_is_valid(abstime)) {
errno = EINVAL;
return -1;
}

View file

@ -4,8 +4,12 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#include "posix_clock.h"
#include <errno.h>
#include <zephyr/kernel.h>
@ -241,11 +245,8 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
struct timer_obj *timer = (struct timer_obj *) timerid;
uint32_t duration, current;
if (timer == NULL ||
value->it_interval.tv_nsec < 0 ||
value->it_interval.tv_nsec >= NSEC_PER_SEC ||
value->it_value.tv_nsec < 0 ||
value->it_value.tv_nsec >= NSEC_PER_SEC) {
if ((timer == NULL) || !timespec_is_valid(&value->it_interval) ||
!timespec_is_valid(&value->it_value)) {
errno = EINVAL;
return -1;
}