mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 04:39:18 +08:00
score: Introduce new monotonic clock
Rename PER_CPU_WATCHDOG_MONOTONIC to PER_CPU_WATCHDOG_TICKS. Add new PER_CPU_WATCHDOG_MONOTONIC which is based on the system uptime (measured by timecounter). Close #3264.
This commit is contained in:
@@ -3112,9 +3112,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
|
||||
const uint32_t _Watchdog_Ticks_per_second = _CONFIGURE_TICKS_PER_SECOND;
|
||||
|
||||
const uint64_t _Watchdog_Monotonic_max_seconds =
|
||||
UINT64_MAX / _CONFIGURE_TICKS_PER_SECOND;
|
||||
|
||||
/**
|
||||
* This is the Classic API Configuration Table.
|
||||
*/
|
||||
|
||||
@@ -248,14 +248,13 @@ typedef struct {
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief Index for monotonic clock per-CPU watchdog header.
|
||||
* @brief Index for tick clock per-CPU watchdog header.
|
||||
*
|
||||
* The reference time point for the monotonic clock is the system start. The
|
||||
* The reference time point for the tick clock is the system start. The
|
||||
* clock resolution is one system clock tick. It is used for the system
|
||||
* clock tick based time services and the POSIX services using
|
||||
* CLOCK_MONOTONIC.
|
||||
* clock tick based time services.
|
||||
*/
|
||||
PER_CPU_WATCHDOG_MONOTONIC,
|
||||
PER_CPU_WATCHDOG_TICKS,
|
||||
|
||||
/**
|
||||
* @brief Index for realtime clock per-CPU watchdog header.
|
||||
@@ -266,6 +265,15 @@ typedef enum {
|
||||
*/
|
||||
PER_CPU_WATCHDOG_REALTIME,
|
||||
|
||||
/**
|
||||
* @brief Index for monotonic clock per-CPU watchdog header.
|
||||
*
|
||||
* The reference time point for the monotonic clock is the system start. The
|
||||
* clock resolution is one nanosecond. It is used for the POSIX services
|
||||
* using CLOCK_MONOTONIC.
|
||||
*/
|
||||
PER_CPU_WATCHDOG_MONOTONIC,
|
||||
|
||||
/**
|
||||
* @brief Count of per-CPU watchdog headers.
|
||||
*/
|
||||
|
||||
@@ -1864,7 +1864,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Timer_initialize(
|
||||
)
|
||||
{
|
||||
_ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
|
||||
timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
_Watchdog_Preinitialize( &timer->Watchdog, cpu );
|
||||
}
|
||||
|
||||
@@ -1879,7 +1879,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Add_timeout_ticks(
|
||||
_ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
|
||||
|
||||
the_thread->Timer.header =
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
the_thread->Timer.Watchdog.routine = _Thread_Timeout;
|
||||
_Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
|
||||
|
||||
@@ -1893,14 +1893,15 @@ RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_realtime(
|
||||
uint64_t expire
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
ISR_lock_Context lock_context;
|
||||
Watchdog_Header *header;
|
||||
|
||||
_ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
|
||||
|
||||
the_thread->Timer.header =
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
|
||||
the_thread->Timer.header = header;
|
||||
the_thread->Timer.Watchdog.routine = routine;
|
||||
_Watchdog_Per_CPU_insert_realtime( &the_thread->Timer.Watchdog, cpu, expire );
|
||||
_Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire );
|
||||
|
||||
_ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
|
||||
}
|
||||
|
||||
@@ -147,15 +147,6 @@ extern const uint32_t _Watchdog_Nanoseconds_per_tick;
|
||||
*/
|
||||
extern const uint32_t _Watchdog_Ticks_per_second;
|
||||
|
||||
/**
|
||||
* @brief The maximum number of seconds representable in the monotonic watchdog
|
||||
* format.
|
||||
*
|
||||
* This constant is defined by the application configuration via
|
||||
* <rtems/confdefs.h>.
|
||||
*/
|
||||
extern const uint64_t _Watchdog_Monotonic_max_seconds;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -303,19 +303,19 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Next_first(
|
||||
* @brief The bits necessary to store 1000000000
|
||||
* (= WATCHDOG_NANOSECONDS_PER_SECOND) nanoseconds.
|
||||
*
|
||||
* The expiration time is an unsigned 64-bit integer. To store absolute
|
||||
* The expiration time is an unsigned 64-bit integer. To store nanoseconds
|
||||
* timeouts we use 30 bits (2**30 == 1073741824) for the nanoseconds and 34
|
||||
* bits for the seconds since UNIX Epoch. This leads to a year 2514 problem.
|
||||
*/
|
||||
#define WATCHDOG_BITS_FOR_1E9_NANOSECONDS 30
|
||||
|
||||
/**
|
||||
* @brief The maximum number of seconds representable in the realtime watchdog
|
||||
* format.
|
||||
* @brief The maximum number of seconds representable in the nanoseconds
|
||||
* watchdog format.
|
||||
*
|
||||
* We have 2**34 bits for the seconds part.
|
||||
*/
|
||||
#define WATCHDOG_REALTIME_MAX_SECONDS 0x3ffffffff
|
||||
#define WATCHDOG_MAX_SECONDS 0x3ffffffff
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_timespec(
|
||||
const struct timespec *ts
|
||||
@@ -362,34 +362,11 @@ RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec(
|
||||
return now;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_monotonic_timespec(
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_timespec(
|
||||
const struct timespec *ts
|
||||
)
|
||||
{
|
||||
return ts->tv_sec >= _Watchdog_Monotonic_max_seconds;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Monotonic_from_timespec(
|
||||
const struct timespec *ts
|
||||
)
|
||||
{
|
||||
uint64_t ticks;
|
||||
|
||||
_Assert( _Watchdog_Is_valid_timespec( ts ) );
|
||||
_Assert( ts->tv_sec >= 0 );
|
||||
_Assert( !_Watchdog_Is_far_future_monotonic_timespec( ts ) );
|
||||
|
||||
ticks = (uint64_t) ts->tv_sec * _Watchdog_Ticks_per_second;
|
||||
ticks += (unsigned long) ts->tv_nsec / _Watchdog_Nanoseconds_per_tick;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_realtime_timespec(
|
||||
const struct timespec *ts
|
||||
)
|
||||
{
|
||||
return ts->tv_sec > WATCHDOG_REALTIME_MAX_SECONDS;
|
||||
return ts->tv_sec > WATCHDOG_MAX_SECONDS;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_seconds(
|
||||
@@ -411,7 +388,7 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_timespec(
|
||||
|
||||
_Assert( _Watchdog_Is_valid_timespec( ts ) );
|
||||
_Assert( ts->tv_sec >= 0 );
|
||||
_Assert( !_Watchdog_Is_far_future_realtime_timespec( ts ) );
|
||||
_Assert( !_Watchdog_Is_far_future_timespec( ts ) );
|
||||
|
||||
ticks = (uint64_t) ts->tv_sec;
|
||||
ticks <<= WATCHDOG_BITS_FOR_1E9_NANOSECONDS;
|
||||
@@ -457,7 +434,7 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks(
|
||||
Watchdog_Header *header;
|
||||
uint64_t expire;
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
|
||||
_Watchdog_Set_CPU( the_watchdog, cpu );
|
||||
|
||||
@@ -468,46 +445,19 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks(
|
||||
return expire;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Watchdog_Per_CPU_lazy_insert_monotonic(
|
||||
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert(
|
||||
Watchdog_Control *the_watchdog,
|
||||
Per_CPU_Control *cpu,
|
||||
Watchdog_Header *header,
|
||||
uint64_t expire
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
Watchdog_Header *header;
|
||||
bool insert;
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Watchdog_Set_CPU( the_watchdog, cpu );
|
||||
|
||||
_Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
|
||||
insert = ( expire > cpu->Watchdog.ticks );
|
||||
|
||||
if ( insert ) {
|
||||
_Watchdog_Insert(header, the_watchdog, expire);
|
||||
}
|
||||
|
||||
_Watchdog_Per_CPU_release_critical( cpu, &lock_context );
|
||||
return insert;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_realtime(
|
||||
Watchdog_Control *the_watchdog,
|
||||
Per_CPU_Control *cpu,
|
||||
uint64_t expire
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
Watchdog_Header *header;
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
|
||||
|
||||
_Watchdog_Set_CPU( the_watchdog, cpu );
|
||||
|
||||
_Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
|
||||
_Watchdog_Insert(header, the_watchdog, expire);
|
||||
_Watchdog_Insert( header, the_watchdog, expire );
|
||||
_Watchdog_Per_CPU_release_critical( cpu, &lock_context );
|
||||
return expire;
|
||||
}
|
||||
@@ -528,7 +478,7 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove(
|
||||
_Watchdog_Per_CPU_release_critical( cpu, &lock_context );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_monotonic(
|
||||
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_ticks(
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
@@ -538,21 +488,7 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_monotonic(
|
||||
_Watchdog_Per_CPU_remove(
|
||||
the_watchdog,
|
||||
cpu,
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_realtime(
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
cpu = _Watchdog_Get_CPU( the_watchdog );
|
||||
_Watchdog_Per_CPU_remove(
|
||||
the_watchdog,
|
||||
cpu,
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,14 +77,14 @@ unsigned int alarm(
|
||||
now = cpu->Watchdog.ticks;
|
||||
|
||||
remaining = (unsigned long) _Watchdog_Cancel(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
the_watchdog,
|
||||
now
|
||||
);
|
||||
|
||||
if ( ticks != 0 ) {
|
||||
_Watchdog_Insert(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
the_watchdog,
|
||||
now + ticks
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/score/timespec.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
#include <rtems/score/timecounter.h>
|
||||
#include <rtems/score/watchdogimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
#include <rtems/seterr.h>
|
||||
@@ -93,7 +93,7 @@ int clock_nanosleep(
|
||||
);
|
||||
}
|
||||
} else {
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &uptime );
|
||||
_Timecounter_Nanouptime( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, rqtp );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
@@ -119,7 +119,7 @@ int clock_nanosleep(
|
||||
if ( eno == EINTR ) {
|
||||
struct timespec actual_end;
|
||||
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &actual_end );
|
||||
_Timecounter_Nanouptime( &actual_end );
|
||||
|
||||
if ( _Timespec_Less_than( &actual_end, end ) ) {
|
||||
_Timespec_Subtract( &actual_end, end, rmtp );
|
||||
|
||||
@@ -69,7 +69,7 @@ void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog )
|
||||
_Priority_Node_set_inactive( &api->Sporadic.Low_priority );
|
||||
}
|
||||
|
||||
_Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );
|
||||
_Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
|
||||
_POSIX_Threads_Sporadic_timer_insert( the_thread, api );
|
||||
|
||||
_Thread_Wait_release( the_thread, &queue_context );
|
||||
@@ -141,7 +141,7 @@ static void _POSIX_Threads_Terminate_extension( Thread_Control *executing )
|
||||
api = executing->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
_Thread_State_acquire( executing, &lock_context );
|
||||
_Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );
|
||||
_Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
|
||||
_Thread_State_release( executing, &lock_context );
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ static int _POSIX_Set_sched_param(
|
||||
|
||||
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
_Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );
|
||||
_Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
|
||||
|
||||
_Priority_Node_set_priority( &the_thread->Real_priority, core_normal_prio );
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ int sigtimedwait(
|
||||
if ( timeout != NULL ) {
|
||||
const struct timespec *end;
|
||||
|
||||
_TOD_Get_zero_based_uptime_as_timespec( &uptime );
|
||||
_Timecounter_Nanouptime( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, timeout );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
|
||||
@@ -56,7 +56,7 @@ int timer_delete(
|
||||
cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
|
||||
ptimer->state = POSIX_TIMER_STATE_FREE;
|
||||
_Watchdog_Remove(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
&ptimer->Timer
|
||||
);
|
||||
_POSIX_Timer_Release( cpu, &lock_context );
|
||||
|
||||
@@ -42,7 +42,7 @@ static void _POSIX_Timer_Insert(
|
||||
_TOD_Get( &ptimer->time );
|
||||
|
||||
_Watchdog_Insert(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
&ptimer->Timer,
|
||||
cpu->Watchdog.ticks + ticks
|
||||
);
|
||||
@@ -152,7 +152,7 @@ int timer_settime(
|
||||
|
||||
/* Stop the timer */
|
||||
_Watchdog_Remove(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
&ptimer->Timer
|
||||
);
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ useconds_t ualarm(
|
||||
now = cpu->Watchdog.ticks;
|
||||
|
||||
remaining = (useconds_t) _Watchdog_Cancel(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
the_watchdog,
|
||||
now
|
||||
);
|
||||
@@ -118,7 +118,7 @@ useconds_t ualarm(
|
||||
cpu = _Per_CPU_Get();
|
||||
_Watchdog_Set_CPU( the_watchdog, cpu );
|
||||
_Watchdog_Insert(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
the_watchdog,
|
||||
now + ticks_initial
|
||||
);
|
||||
|
||||
@@ -32,7 +32,7 @@ void _Rate_monotonic_Cancel(
|
||||
|
||||
_Rate_monotonic_Acquire_critical( the_period, lock_context );
|
||||
|
||||
_Watchdog_Per_CPU_remove_monotonic( &the_period->Timer );
|
||||
_Watchdog_Per_CPU_remove_ticks( &the_period->Timer );
|
||||
the_period->state = RATE_MONOTONIC_INACTIVE;
|
||||
_Scheduler_Cancel_job(
|
||||
the_period->owner,
|
||||
|
||||
@@ -72,7 +72,7 @@ rtems_status_code _Timer_Fire(
|
||||
|
||||
if ( _Timer_Is_interval_class( the_class ) ) {
|
||||
_Watchdog_Insert(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
&the_timer->Ticker,
|
||||
cpu->Watchdog.ticks + interval
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ rtems_status_code rtems_timer_reset(
|
||||
if ( _Timer_Is_interval_class( the_timer->the_class ) ) {
|
||||
_Timer_Cancel( cpu, the_timer );
|
||||
_Watchdog_Insert(
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
|
||||
&the_timer->Ticker,
|
||||
cpu->Watchdog.ticks + the_timer->initial
|
||||
);
|
||||
|
||||
@@ -34,50 +34,13 @@ void _Thread_queue_Add_timeout_ticks(
|
||||
}
|
||||
}
|
||||
|
||||
static bool _Thread_queue_Lazy_insert_monotonic_timespec(
|
||||
static void _Thread_queue_Add_timeout_timespec(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *the_thread,
|
||||
Per_CPU_Control *cpu_self,
|
||||
const struct timespec *abstime
|
||||
)
|
||||
{
|
||||
uint64_t expire;
|
||||
ISR_lock_Context lock_context;
|
||||
bool insert;
|
||||
|
||||
if ( abstime->tv_sec < 0 ) {
|
||||
expire = 0;
|
||||
} else if ( _Watchdog_Is_far_future_monotonic_timespec( abstime ) ) {
|
||||
expire = WATCHDOG_MAXIMUM_TICKS;
|
||||
} else {
|
||||
expire = _Watchdog_Monotonic_from_timespec( abstime );
|
||||
}
|
||||
|
||||
_ISR_lock_ISR_disable_and_acquire(
|
||||
&the_thread->Timer.Lock,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
the_thread->Timer.header =
|
||||
&cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
the_thread->Timer.Watchdog.routine = _Thread_Timeout;
|
||||
insert = _Watchdog_Per_CPU_lazy_insert_monotonic(
|
||||
&the_thread->Timer.Watchdog,
|
||||
cpu_self,
|
||||
expire
|
||||
);
|
||||
|
||||
_ISR_lock_Release_and_ISR_enable(
|
||||
&the_thread->Timer.Lock,
|
||||
&lock_context
|
||||
);
|
||||
return insert;
|
||||
}
|
||||
|
||||
void _Thread_queue_Add_timeout_monotonic_timespec(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *the_thread,
|
||||
Per_CPU_Control *cpu_self,
|
||||
Thread_queue_Context *queue_context
|
||||
Thread_queue_Context *queue_context,
|
||||
Watchdog_Header *header,
|
||||
const struct timespec *now
|
||||
)
|
||||
{
|
||||
const struct timespec *abstime;
|
||||
@@ -85,46 +48,17 @@ void _Thread_queue_Add_timeout_monotonic_timespec(
|
||||
abstime = queue_context->Timeout.arg;
|
||||
|
||||
if ( _Watchdog_Is_valid_timespec( abstime ) ) {
|
||||
if (
|
||||
!_Thread_queue_Lazy_insert_monotonic_timespec(
|
||||
the_thread,
|
||||
cpu_self,
|
||||
abstime
|
||||
)
|
||||
) {
|
||||
_Thread_Continue( the_thread, STATUS_TIMEOUT );
|
||||
}
|
||||
} else {
|
||||
_Thread_Continue( the_thread, STATUS_INVALID_NUMBER );
|
||||
}
|
||||
}
|
||||
|
||||
void _Thread_queue_Add_timeout_realtime_timespec(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *the_thread,
|
||||
Per_CPU_Control *cpu_self,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
const struct timespec *abstime;
|
||||
|
||||
abstime = queue_context->Timeout.arg;
|
||||
|
||||
if ( _Watchdog_Is_valid_timespec( abstime ) ) {
|
||||
uint64_t expire;
|
||||
struct timespec now;
|
||||
uint64_t expire;
|
||||
|
||||
if ( abstime->tv_sec < 0 ) {
|
||||
expire = 0;
|
||||
} else if ( _Watchdog_Is_far_future_realtime_timespec( abstime ) ) {
|
||||
} else if ( _Watchdog_Is_far_future_timespec( abstime ) ) {
|
||||
expire = WATCHDOG_MAXIMUM_TICKS;
|
||||
} else {
|
||||
expire = _Watchdog_Ticks_from_timespec( abstime );
|
||||
}
|
||||
|
||||
_Timecounter_Getnanotime( &now );
|
||||
|
||||
if ( expire > _Watchdog_Ticks_from_timespec( &now ) ) {
|
||||
if ( expire > _Watchdog_Ticks_from_timespec( now ) ) {
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_ISR_lock_ISR_disable_and_acquire(
|
||||
@@ -132,12 +66,12 @@ void _Thread_queue_Add_timeout_realtime_timespec(
|
||||
&lock_context
|
||||
);
|
||||
|
||||
the_thread->Timer.header =
|
||||
&cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
|
||||
the_thread->Timer.header = header;
|
||||
the_thread->Timer.Watchdog.routine = _Thread_Timeout;
|
||||
_Watchdog_Per_CPU_insert_realtime(
|
||||
_Watchdog_Per_CPU_insert(
|
||||
&the_thread->Timer.Watchdog,
|
||||
cpu_self,
|
||||
header,
|
||||
expire
|
||||
);
|
||||
|
||||
@@ -152,3 +86,43 @@ void _Thread_queue_Add_timeout_realtime_timespec(
|
||||
_Thread_Continue( the_thread, STATUS_INVALID_NUMBER );
|
||||
}
|
||||
}
|
||||
|
||||
void _Thread_queue_Add_timeout_monotonic_timespec(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *the_thread,
|
||||
Per_CPU_Control *cpu_self,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
_Timecounter_Getnanouptime( &now );
|
||||
_Thread_queue_Add_timeout_timespec(
|
||||
queue,
|
||||
the_thread,
|
||||
cpu_self,
|
||||
queue_context,
|
||||
&cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
|
||||
&now
|
||||
);
|
||||
}
|
||||
|
||||
void _Thread_queue_Add_timeout_realtime_timespec(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *the_thread,
|
||||
Per_CPU_Control *cpu_self,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
_Timecounter_Getnanotime( &now );
|
||||
_Thread_queue_Add_timeout_timespec(
|
||||
queue,
|
||||
the_thread,
|
||||
cpu_self,
|
||||
queue_context,
|
||||
&cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ],
|
||||
&now
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ void _Watchdog_Tick( Per_CPU_Control *cpu )
|
||||
++ticks;
|
||||
cpu->Watchdog.ticks = ticks;
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
first = _Watchdog_Header_first( header );
|
||||
|
||||
if ( first != NULL ) {
|
||||
@@ -83,6 +83,20 @@ void _Watchdog_Tick( Per_CPU_Control *cpu )
|
||||
);
|
||||
}
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
first = _Watchdog_Header_first( header );
|
||||
|
||||
if ( first != NULL ) {
|
||||
_Timecounter_Getnanouptime( &now );
|
||||
_Watchdog_Tickle(
|
||||
header,
|
||||
first,
|
||||
_Watchdog_Ticks_from_timespec( &now ),
|
||||
&cpu->Watchdog.Lock,
|
||||
&lock_context
|
||||
);
|
||||
}
|
||||
|
||||
header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
|
||||
first = _Watchdog_Header_first( header );
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ static rtems_timer_service_routine test_release_from_isr(
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu = _Per_CPU_Get();
|
||||
Watchdog_Header *header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
Watchdog_Header *header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
Watchdog_Control *watchdog = (Watchdog_Control *) header->first;
|
||||
|
||||
if (
|
||||
@@ -55,7 +55,7 @@ static rtems_timer_service_routine test_release_from_isr(
|
||||
) {
|
||||
Thread_Wait_flags flags = _Thread_Wait_flags_get( thread );
|
||||
|
||||
_Watchdog_Per_CPU_remove_monotonic( watchdog );
|
||||
_Watchdog_Per_CPU_remove_ticks( watchdog );
|
||||
|
||||
rtems_test_assert( getState() == RATE_MONOTONIC_ACTIVE );
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ static rtems_timer_service_routine test_release_from_isr(
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu_self = _Per_CPU_Get();
|
||||
Watchdog_Header *header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
|
||||
Watchdog_Header *header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
|
||||
Watchdog_Control *watchdog = (Watchdog_Control *) header->first;
|
||||
|
||||
if (
|
||||
|
||||
@@ -59,7 +59,6 @@ static void test_watchdog_config( void )
|
||||
{
|
||||
rtems_test_assert( _Watchdog_Nanoseconds_per_tick == 10000000 );
|
||||
rtems_test_assert( _Watchdog_Ticks_per_second == 100 );
|
||||
rtems_test_assert( _Watchdog_Monotonic_max_seconds == 184467440737095516 );
|
||||
rtems_test_assert( rtems_clock_get_ticks_per_second() == 100 );
|
||||
#undef rtems_clock_get_ticks_per_second
|
||||
rtems_test_assert( rtems_clock_get_ticks_per_second() == 100 );
|
||||
|
||||
Reference in New Issue
Block a user