Skip to content

Commit

Permalink
tests/kernel/schedule_api: Fix slop in timeslice test
Browse files Browse the repository at this point in the history
This test is a little subtle: it wants to spawn three threads to run
and be switched out by a timeslice interrupt.  And it wants to consume
half a time slice itself before it starts running.  And, because
timeslicing runs out of the same tick framework in the timer driver,
it needs to align to the start of a tick before the process starts.
And further: it does its own time math not in ticks but in timer
cycles, so it's quite sensitive to slop.

But it's "synchronize to tick boundary" code was actually
synchronizing to a CYCLE boundary, which is just wrong.  And it was
doing this in the wrong order.  It was resetting the timeslice first
and then synchronizing to a tick by spinning, which means that the
test was always going to begin as much as a tick late.  Do the tick
synchronization (via a sleep) first.

Finally, the manager thread that was spawning the new threads lives at
the same priority as the highest priority child threads, which means
it can potentitially wake up on the semaphores that they are giving in
the middle of the test and consume CPU unexpectedly.  Make sure it's
sleeping for the duration.

Signed-off-by: Andy Ross <[email protected]>
  • Loading branch information
Andy Ross authored and nashif committed Oct 29, 2020
1 parent b7d3054 commit 0875740
Showing 1 changed file with 7 additions and 10 deletions.
17 changes: 7 additions & 10 deletions tests/kernel/sched/schedule_api/src/test_sched_timeslice_reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,25 +134,21 @@ void test_slice_reset(void)
/* update priority for current thread */
k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(j));

/* synchronize to tick boundary */
k_usleep(1);

/* create delayed threads with equal preemptive priority */
for (int i = 0; i < NUM_THREAD; i++) {
tid[i] = k_thread_create(&t[i], tstacks[i], STACK_SIZE,
thread_time_slice, NULL, NULL,
NULL, K_PRIO_PREEMPT(j), 0,
K_NO_WAIT);
}
/* enable time slice */
k_sched_time_slice_set(SLICE_SIZE, K_PRIO_PREEMPT(0));

/* synchronize to tick boundary */
t32 = k_uptime_get_32();
while (k_uptime_get_32() == t32) {
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#endif
}
/* enable time slice (and reset the counter!) */
k_sched_time_slice_set(SLICE_SIZE, K_PRIO_PREEMPT(0));

/* set reference time */
/* initialize reference timestamp */
cycles_delta(&elapsed_slice);

/* current thread (ztest native) consumed a half timeslice */
Expand All @@ -164,6 +160,7 @@ void test_slice_reset(void)
}

/* relinquish CPU and wait for each thread to complete */
k_msleep(SLICE_SIZE * (NUM_THREAD + 1));
for (int i = 0; i < NUM_THREAD; i++) {
k_sem_take(&sema, K_FOREVER);
}
Expand Down

0 comments on commit 0875740

Please sign in to comment.