Skip to content

RTOS: SysTimer: Fix test timing issues #9416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2019

Conversation

fkjagodzinski
Copy link
Member

Description

Use a busy loop with non-blocking Semaphore::wait(0) calls instead of a
single Semaphore::wait(osWaitForever) to improve time measurement
accuracy.

This should resolve #9400.

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[ ] Functionality change
[ ] Docs update
[x] Test update
[ ] Breaking change

Reviewers

@c1728p9 @jeromecoutant

@ciarmcom
Copy link
Member

@fkjagodzinski, thank you for your changes.
@c1728p9 @ARMmbed/mbed-os-core @ARMmbed/mbed-os-test @ARMmbed/mbed-os-maintainers please review.

@ciarmcom ciarmcom requested review from c1728p9 and a team January 17, 2019 18:00
@deepikabhavnani
Copy link

Use a busy loop with non-blocking Semaphore::wait(0) calls instead of a single Semaphore::wait(osWaitForever) to improve time measurement accuracy.

Please share some background information on this, how will it improve time measurement?
I believe we are not saying that code below(changed) takes less time then sem_slots = st.sem_wait(osWaitForever);

  while (sem_slots != 1) {
        sem_slots = st.sem_wait(0);
    }

Copy link
Collaborator

@jeromecoutant jeromecoutant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test is 100% OK with all STM32L0 and STM32L4 targets now!

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 18, 2019

@deepikabhavnani good question !

Can we have the answer captured in the commit msg (why are we changing this code - both are valid, arenth they)

@fkjagodzinski
Copy link
Member Author

Please share some background information on this, how will it improve time measurement?

@deepikabhavnani, @0xc0170 This patch prevents the board from entering sleep or deepsleep modes while waiting for the semaphore. The difference can be seen with this code (which is just a simplified version of the code from the test).

#ifndef MBED_TICKLESS
#error Tickless mode not supported for this target.
#endif

#if !DEVICE_LPTICKER
#error Current SysTimer implementation requires lp ticker support.
#endif

#ifndef MBED_CPU_STATS_ENABLED
#error Please set MBED_CPU_STATS_ENABLED to see the sleep stats
#endif

#include "mbed.h"
extern "C" {
#include "rtx_lib.h"
}
#include "rtos/TARGET_CORTEX/SysTimer.h"

#define TEST_TICKS 42UL

const us_timestamp_t DELAY_US = 1000000ULL * TEST_TICKS / OS_TICK_FREQ;

// Override the handler() -- the SysTick interrupt must not be set as pending by the test code.
class SysTimerTest: public rtos::internal::SysTimer {
private:
    Semaphore _sem;
    virtual void handler()
    {
        core_util_critical_section_enter();
        _increment_tick();
        core_util_critical_section_exit();
        _sem.release();
    }

public:
    SysTimerTest() :
        SysTimer(), _sem(0, 1)
    {
    }

    SysTimerTest(const ticker_data_t *data) :
        SysTimer(data), _sem(0, 1)
    {
    }

    virtual ~SysTimerTest()
    {
    }

    int32_t sem_wait(uint32_t millisec)
    {
        return _sem.wait(millisec);
    }
};

int main()
{
    SysTimerTest st;
    st.schedule_tick(TEST_TICKS);
    us_timestamp_t t1 = st.get_time();
    int32_t sem_slots = 0;

#ifdef SEM_WAIT_FOREVER
#define WAIT_METHOD "osWaitForever"
    sem_slots = st.sem_wait(osWaitForever);
#else
#define WAIT_METHOD "busy_loop"
    while (sem_slots != 1) {
        sem_slots = st.sem_wait(0);
    }
#endif

    us_timestamp_t t2 = st.get_time();

    us_timestamp_t t_idle = mbed_time_idle();
    us_timestamp_t t_sleep = mbed_time_sleep();
    us_timestamp_t t_deepsleep = mbed_time_deepsleep();

    printf("%15s%15s\r\n", "wait_method = ", WAIT_METHOD);
    printf("%15s%15llu\r\n", "t_idle = ", t_idle);
    printf("%15s%15llu\r\n", "t_sleep = ", t_sleep);
    printf("%15s%15llu\r\n", "t_deepsleep = ", t_deepsleep);
    printf("%15s%15llu\r\n\r\n", "t2 - t1 = ", t2 - t1);
}
mbed compile -t GCC_ARM -m NUCLEO_L476RG -f --sterm -DMBED_CPU_STATS_ENABLED -DSEM_WAIT_FOREVER

gives:

 wait_method =   osWaitForever
      t_idle =           44220
     t_sleep =             122
 t_deepsleep =           44098
     t2 - t1 =           44586
mbed compile -t GCC_ARM -m NUCLEO_L476RG -f --sterm -DMBED_CPU_STATS_ENABLED

gives:

 wait_method =       busy_loop
      t_idle =               0
     t_sleep =               0
 t_deepsleep =               0
     t2 - t1 =           42083

Copy link

@deepikabhavnani deepikabhavnani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explanation @fkjagodzinski. Looks good to me 👍

It will be good to add below line to the commit message
"Looping in Semaphore::wait(0) prevents the board from entering sleep or deepsleep modes while waiting for the semaphore. By skipping the overhead wakeup time, we get more accurate timings"

Use a busy loop with non-blocking Semaphore::wait(0) calls instead of a
single Semaphore::wait(osWaitForever) to improve time measurement
accuracy. Looping in Semaphore::wait(0) prevents the board from entering
sleep or deepsleep modes while waiting for the semaphore. By skipping
the overhead wakeup time, we get more accurate timings.
@fkjagodzinski
Copy link
Member Author

I've added a short comment in the code and updated the commit message as suggested.

@cmonr cmonr changed the title ROTS: SysTimer: Fix test timing issues RTOS: SysTimer: Fix test timing issues Jan 18, 2019
@cmonr
Copy link
Contributor

cmonr commented Jan 18, 2019

CI started

@mbed-ci
Copy link

mbed-ci commented Jan 19, 2019

Test run: SUCCESS

Summary: 9 of 9 test jobs passed
Build number : 1
Build artifacts

@0xc0170 0xc0170 merged commit a09b5f5 into ARMmbed:master Jan 21, 2019
@fkjagodzinski fkjagodzinski deleted the test_update-systimer branch February 1, 2019 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

tests-mbedmicro-rtos-mbed-systimer to tune ?
8 participants