tests: interrupt: fix broken scenario

The author of this test case seems to have been under the
mistaken impression that interrupts are locked in ISRs, which
is untrue.

The only reason this ever passed, anywhere, was a race between
the timer firing and the zassert_not_equal() check in
offload_function. If the busy_wait call is moved after the timer
is started, this fails everywhere.

We do not re-use the timer object from the previous case,
resolving some crashes observed on riscv.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-02-19 10:33:17 -08:00 committed by Anas Nashif
commit 7eb07d1470

View file

@ -7,6 +7,7 @@
#define DURATION 5
struct k_timer timer;
struct k_timer irqlock_timer;
/* This tests uses two IRQ lines, selected within the range of IRQ lines
* available on the target SOC the test executes on (and starting from
@ -134,22 +135,36 @@ static void timer_handler(struct k_timer *timer)
{
ARG_UNUSED(timer);
check_lock_new = 0xBEEF;
}
static void offload_function(void *param)
{
ARG_UNUSED(param);
zassert_true(k_is_in_isr(), "Not in IRQ context!");
k_timer_init(&timer, timer_handler, NULL);
k_busy_wait(MS_TO_US(1));
k_timer_start(&timer, DURATION, K_NO_WAIT);
zassert_not_equal(check_lock_new, check_lock_old,
"Interrupt locking didn't work properly");
printk("timer fired\n");
}
void test_prevent_interruption(void)
{
irq_offload(offload_function, NULL);
k_timer_stop(&timer);
int key;
printk("locking interrupts\n");
key = irq_lock();
check_lock_new = 0;
k_timer_init(&irqlock_timer, timer_handler, NULL);
/* Start the timer and busy-wait for a bit with IRQs locked. The
* timer ought to have fired during this time if interrupts weren't
* locked -- but since they are, check_lock_new isn't updated.
*/
k_timer_start(&irqlock_timer, DURATION, K_NO_WAIT);
k_busy_wait(MS_TO_US(1000));
zassert_not_equal(check_lock_new, check_lock_old,
"Interrupt locking didn't work properly");
printk("unlocking interrupts\n");
irq_unlock(key);
k_busy_wait(MS_TO_US(1000));
zassert_equal(check_lock_new, check_lock_old,
"timer should have fired");
k_timer_stop(&irqlock_timer);
}