mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 18:18:16 +08:00
@@ -63,7 +63,7 @@ int clock_nanosleep(
|
||||
)
|
||||
{
|
||||
Thread_queue_Context queue_context;
|
||||
struct timespec spare_end;
|
||||
struct timespec uptime;
|
||||
const struct timespec *end;
|
||||
Thread_Control *executing;
|
||||
int eno;
|
||||
@@ -93,16 +93,8 @@ int clock_nanosleep(
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ( !_Watchdog_Is_valid_interval_timespec( rqtp ) ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &spare_end );
|
||||
|
||||
/* In case this overflows, then the enqueue callout will reject it */
|
||||
_Timespec_Add_to( &spare_end, rqtp );
|
||||
|
||||
end = &spare_end;
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, rqtp );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
|
||||
@@ -76,6 +76,7 @@ int sigtimedwait(
|
||||
siginfo_t signal_information;
|
||||
siginfo_t *the_info;
|
||||
int signo;
|
||||
struct timespec uptime;
|
||||
Thread_queue_Context queue_context;
|
||||
int error;
|
||||
|
||||
@@ -92,20 +93,13 @@ int sigtimedwait(
|
||||
*/
|
||||
|
||||
if ( timeout != NULL ) {
|
||||
struct timespec end;
|
||||
|
||||
if ( !_Watchdog_Is_valid_interval_timespec( timeout ) ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &end );
|
||||
|
||||
/* In case this overflows, then the enqueue callout will reject it */
|
||||
_Timespec_Add_to( &end, timeout );
|
||||
const struct timespec *end;
|
||||
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, timeout );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
&end
|
||||
end
|
||||
);
|
||||
} else {
|
||||
_Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
|
||||
|
||||
@@ -324,6 +324,36 @@ RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_interval_timespec(
|
||||
return _Watchdog_Is_valid_timespec( ts ) && ts->tv_sec >= 0;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec(
|
||||
struct timespec *now,
|
||||
const struct timespec *delta
|
||||
)
|
||||
{
|
||||
uint64_t sec;
|
||||
|
||||
if ( !_Watchdog_Is_valid_interval_timespec( delta ) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sec = (uint64_t) now->tv_sec;
|
||||
sec += (uint64_t) delta->tv_sec;
|
||||
now->tv_nsec += delta->tv_nsec;
|
||||
|
||||
/* We have 2 * (2**63 - 1) + 1 == UINT64_MAX */
|
||||
if ( now->tv_nsec >= WATCHDOG_NANOSECONDS_PER_SECOND ) {
|
||||
now->tv_nsec -= WATCHDOG_NANOSECONDS_PER_SECOND;
|
||||
++sec;
|
||||
}
|
||||
|
||||
if ( sec <= INT64_MAX ) {
|
||||
now->tv_sec = sec;
|
||||
} else {
|
||||
now->tv_sec = INT64_MAX;
|
||||
}
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_monotonic_timespec(
|
||||
const struct timespec *ts
|
||||
)
|
||||
|
||||
@@ -13,19 +13,17 @@
|
||||
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pmacros.h"
|
||||
#include "pritime.h"
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
const char rtems_test_name[] = "PSXCLOCK";
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument argument);
|
||||
void check_enosys(int status);
|
||||
|
||||
void check_enosys(int status)
|
||||
static void check_enosys(int status)
|
||||
{
|
||||
if ( (status == -1) && (errno == ENOSYS) )
|
||||
return;
|
||||
@@ -33,7 +31,52 @@ void check_enosys(int status)
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
rtems_task Init(
|
||||
typedef struct {
|
||||
int counter;
|
||||
struct timespec delta;
|
||||
} nanosleep_contex;
|
||||
|
||||
static void task_nanosleep( rtems_task_argument arg )
|
||||
{
|
||||
nanosleep_contex *ctx;
|
||||
|
||||
ctx = (nanosleep_contex *) arg;
|
||||
++ctx->counter;
|
||||
nanosleep( &ctx->delta, NULL );
|
||||
}
|
||||
|
||||
static void test_far_future_nanosleep( void )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id id;
|
||||
nanosleep_contex ctx;
|
||||
|
||||
sc = rtems_task_create(
|
||||
rtems_build_name( 'N', 'A', 'N', 'O' ),
|
||||
1,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&id
|
||||
);
|
||||
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
|
||||
|
||||
ctx.counter = 0;
|
||||
ctx.delta.tv_sec = INT64_MAX;
|
||||
ctx.delta.tv_nsec = 999999999;
|
||||
sc = rtems_task_start( id, task_nanosleep, (rtems_task_argument) &ctx );
|
||||
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
|
||||
|
||||
sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
|
||||
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
|
||||
|
||||
rtems_test_assert( ctx.counter == 1 );
|
||||
|
||||
sc = rtems_task_delete( id );
|
||||
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
|
||||
}
|
||||
|
||||
static rtems_task Init(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
@@ -140,6 +183,8 @@ rtems_task Init(
|
||||
printf( "Init: seconds remaining (%d)\n", (int)remaining );
|
||||
rtems_test_assert( !remaining );
|
||||
|
||||
test_far_future_nanosleep();
|
||||
|
||||
/* error cases in nanosleep */
|
||||
|
||||
empty_line();
|
||||
@@ -267,7 +312,7 @@ rtems_task Init(
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||
#define CONFIGURE_MAXIMUM_TASKS 2
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#include <rtems/confdefs.h>
|
||||
|
||||
Reference in New Issue
Block a user