forked from Imagelibrary/rtems
bsps/clock: Fix fast idle clock tick support
If we interrupt a thread dispatch critical section (thread dispatch disable level != ISR nest level), then we should not do the fast idle mode since this may delay an ongoing system call forever.
This commit is contained in:
@@ -98,15 +98,21 @@ void clockOn(void* unused)
|
|||||||
static void clockHandler(void)
|
static void clockHandler(void)
|
||||||
{
|
{
|
||||||
#if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
|
#if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
uint32_t tb;
|
uint32_t tb;
|
||||||
|
Per_CPU_Control *cpu_self;
|
||||||
|
|
||||||
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
tb = ppc_time_base();
|
tb = ppc_time_base();
|
||||||
rtems_timecounter_tick();
|
rtems_timecounter_tick();
|
||||||
|
cpu_self = _Per_CPU_Get();
|
||||||
|
|
||||||
while ( _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle ) {
|
while (
|
||||||
|
cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level
|
||||||
|
&& cpu_self->heir == cpu_self->executing
|
||||||
|
&& cpu_self->executing->is_idle
|
||||||
|
) {
|
||||||
tb += Clock_Decrementer_value;
|
tb += Clock_Decrementer_value;
|
||||||
ppc_set_time_base( tb );
|
ppc_set_time_base( tb );
|
||||||
rtems_timecounter_tick();
|
rtems_timecounter_tick();
|
||||||
|
|||||||
@@ -143,16 +143,23 @@ rtems_isr Clock_isr(
|
|||||||
|
|
||||||
#if CLOCK_DRIVER_USE_FAST_IDLE
|
#if CLOCK_DRIVER_USE_FAST_IDLE
|
||||||
{
|
{
|
||||||
struct timecounter *tc = _Timecounter;
|
|
||||||
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
|
||||||
uint32_t interval = (uint32_t)
|
|
||||||
((tc->tc_frequency * us_per_tick) / 1000000);
|
|
||||||
|
|
||||||
Clock_driver_timecounter_tick();
|
Clock_driver_timecounter_tick();
|
||||||
|
|
||||||
if (_SMP_Get_processor_maximum() == 1) {
|
if (_SMP_Get_processor_maximum() == 1) {
|
||||||
|
struct timecounter *tc;
|
||||||
|
uint64_t us_per_tick;
|
||||||
|
uint32_t interval;
|
||||||
|
Per_CPU_Control *cpu_self;
|
||||||
|
|
||||||
|
cpu_self = _Per_CPU_Get();
|
||||||
|
tc = _Timecounter;
|
||||||
|
us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||||
|
interval = (uint32_t) ((tc->tc_frequency * us_per_tick) / 1000000);
|
||||||
|
|
||||||
while (
|
while (
|
||||||
_Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
|
cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level
|
||||||
|
&& cpu_self->heir == cpu_self->executing
|
||||||
|
&& cpu_self->executing->is_idle
|
||||||
) {
|
) {
|
||||||
ISR_lock_Context lock_context;
|
ISR_lock_Context lock_context;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user