mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 08:48:35 +08:00
Test needed for timer_create with CLOCK_MONOTONC
the timer_create() method can use CLOCK_MONOTONIC but there was no test for this. Also it implements the functionality to create a CLOCK_MONOTONIC timer and gettime() . Closes #3888
This commit is contained in:
committed by
Joel Sherrill
parent
c71e34bee0
commit
8df57649b0
@@ -48,6 +48,7 @@ typedef struct {
|
||||
uint32_t ticks; /* Number of ticks of the initialization */
|
||||
uint32_t overrun; /* Number of expirations of the timer */
|
||||
struct timespec time; /* Time at which the timer was started */
|
||||
clockid_t clock_type; /* The type of timer */
|
||||
} POSIX_Timer_Control;
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ int timer_create(
|
||||
{
|
||||
POSIX_Timer_Control *ptimer;
|
||||
|
||||
if ( clock_id != CLOCK_REALTIME )
|
||||
if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( !timerid )
|
||||
@@ -91,6 +91,7 @@ int timer_create(
|
||||
ptimer->timer_data.it_value.tv_nsec = 0;
|
||||
ptimer->timer_data.it_interval.tv_sec = 0;
|
||||
ptimer->timer_data.it_interval.tv_nsec = 0;
|
||||
ptimer->clock_type = clock_id;
|
||||
|
||||
_Watchdog_Preinitialize( &ptimer->Timer, _Per_CPU_Get_snapshot() );
|
||||
_Watchdog_Initialize( &ptimer->Timer, _POSIX_Timer_TSR );
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <rtems/score/todimpl.h>
|
||||
#include <rtems/score/watchdogimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
#include <rtems/timespec.h>
|
||||
|
||||
/*
|
||||
* - When a timer is initialized, the value of the time in
|
||||
@@ -42,32 +43,43 @@ int timer_gettime(
|
||||
)
|
||||
{
|
||||
POSIX_Timer_Control *ptimer;
|
||||
ISR_lock_Context lock_context;
|
||||
uint64_t now;
|
||||
uint32_t remaining;
|
||||
ISR_lock_Context lock_context;
|
||||
Per_CPU_Control *cpu;
|
||||
struct timespec now;
|
||||
struct timespec expire;
|
||||
struct timespec result;
|
||||
|
||||
if ( !value )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
ptimer = _POSIX_Timer_Get( timerid, &lock_context );
|
||||
if ( ptimer != NULL ) {
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
|
||||
now = cpu->Watchdog.ticks;
|
||||
|
||||
if ( now < ptimer->Timer.expire ) {
|
||||
remaining = (uint32_t) ( ptimer->Timer.expire - now );
|
||||
} else {
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
_Timespec_From_ticks( remaining, &value->it_value );
|
||||
value->it_interval = ptimer->timer_data.it_interval;
|
||||
|
||||
_POSIX_Timer_Release( cpu, &lock_context );
|
||||
return 0;
|
||||
if ( ptimer == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
|
||||
rtems_timespec_from_ticks( ptimer->Timer.expire, &expire );
|
||||
|
||||
if ( ptimer->clock_type == CLOCK_MONOTONIC ) {
|
||||
_Timecounter_Nanouptime(&now);
|
||||
} else if (ptimer->clock_type == CLOCK_REALTIME) {
|
||||
_TOD_Get(&now);
|
||||
} else {
|
||||
_POSIX_Timer_Release( cpu, &lock_context );
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
|
||||
if ( rtems_timespec_less_than( &now, &expire ) ) {
|
||||
rtems_timespec_subtract( &now, &expire, &result );
|
||||
} else {
|
||||
result.tv_nsec = 0;
|
||||
result.tv_sec = 0;
|
||||
}
|
||||
|
||||
value->it_value = result;
|
||||
value->it_interval = ptimer->timer_data.it_interval;
|
||||
|
||||
_POSIX_Timer_Release( cpu, &lock_context );
|
||||
return 0;
|
||||
}
|
||||
@@ -127,6 +127,32 @@ void *POSIX_Init (
|
||||
status = timer_delete( timer );
|
||||
fatal_posix_service_status_errno( status, EINVAL, "bad id" );
|
||||
|
||||
puts( "timer_create (monotonic) - bad timer id pointer - EINVAL" );
|
||||
status = timer_create( CLOCK_MONOTONIC, &event, NULL );
|
||||
fatal_posix_service_status_errno( status, EINVAL, "bad timer id" );
|
||||
|
||||
puts( "timer_create (monotonic) - OK" );
|
||||
status = timer_create( CLOCK_MONOTONIC, NULL, &timer );
|
||||
posix_service_failed( status, "timer_create OK" );
|
||||
|
||||
puts( "timer_create (monotonic) - too many - EAGAIN" );
|
||||
status = timer_create( CLOCK_MONOTONIC, NULL, &timer1 );
|
||||
fatal_posix_service_status_errno( status, EAGAIN, "too many" );
|
||||
|
||||
clock_gettime( CLOCK_MONOTONIC, &now );
|
||||
itimer.it_value = now;
|
||||
itimer.it_value.tv_sec = itimer.it_value.tv_sec - 1;
|
||||
puts( "timer_settime (monotonic) - bad itimer value - previous time - EINVAL" );
|
||||
status = timer_settime( timer, TIMER_ABSTIME, &itimer, NULL );
|
||||
fatal_posix_service_status_errno( status, EINVAL, "bad itimer value #3" );
|
||||
|
||||
clock_gettime( CLOCK_MONOTONIC, &now );
|
||||
itimer.it_value = now;
|
||||
itimer.it_value.tv_sec = itimer.it_value.tv_sec + 1;
|
||||
puts( "timer_settime (monotonic) - bad id - EINVAL" );
|
||||
status = timer_settime( timer1, TIMER_ABSTIME, &itimer, NULL );
|
||||
fatal_posix_service_status_errno( status, EINVAL, "bad id" );
|
||||
|
||||
TEST_END();
|
||||
rtems_test_exit (0);
|
||||
}
|
||||
|
||||
@@ -13,4 +13,9 @@ timer_settime - bad itimer value - negative nanosecond - EINVAL
|
||||
timer_settime - bad clock value - EINVAL
|
||||
timer_delete - OK
|
||||
timer_delete - bad id - EINVAL
|
||||
timer_create (monotonic) - bad timer id pointer - EINVAL
|
||||
timer_create (monotonic) - OK
|
||||
timer_create (monotonic) - too many - EAGAIN
|
||||
timer_settime (monotonic) - bad itimer value - previous time - EINVAL
|
||||
timer_settime (monotonic) - bad id - EINVAL
|
||||
*** END OF POSIX Timers Test 02 ***
|
||||
|
||||
Reference in New Issue
Block a user