Virtual timer overflow Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
steved
Posts: 633
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 6 times
Been thanked: 89 times

Virtual timer overflow  Topic is solved

Postby steved » Wed May 22, 2019 6:37 pm

Not sure if this is a bug or a constraint.

ChibiOs 19.1.2
Using 32L071, so 16-bit SYSTICK at 1kHz.
CH_CFG_INTERVALS_SIZE 32
CH_CFG_TIME_TYPES_SIZE 32
All diagnostics enabled

I have a virtual timer started for a 5-minute interval (so multiple cycles of SYSTICK).
It appears that this can be handled as long as there are other virtual timers active - the outstanding tick count is clearly being reduced progressively.
Occasionally this 5-minute timer is the only one active; I then get a halt triggered by overflow in chTimeAddX() in line 134 of chvt.c.

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Wed May 22, 2019 7:04 pm

Hi,

Interesting corner case, I need to verify. It is possible that flashing leds in the various demos hid this.

Giovanni

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Thu May 23, 2019 9:34 am

Confirmed, there is a problem under those conditions, will be fixed over weekend.

Giovanni

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Sun May 26, 2019 7:48 am

Hi,

The fix is to replace line 453 in chvt.h:

Code: Select all

  delta = chTimeDiffX(now, chTimeAddX(ch.vtlist.lasttime, vtp->delta));


with this:

Code: Select all

  delta = vtp->delta - chTimeDiffX(ch.vtlist.lasttime, now);


which calculates the delta in the "intervals domain" instead of "absolute time domain" like the previous expression. The two things are not equivalent because the different type size.

Opening a ticket about this, thanks for finding.

Giovanni

faisal
Posts: 253
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 35 times
Been thanked: 32 times

Re: Virtual timer overflow

Postby faisal » Mon May 27, 2019 5:00 pm

Will a test case be added to test for this?

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Mon May 27, 2019 6:28 pm

Probably but it will be "conditional", executed only when the kernel is configured in the right mode: tickless and (sizeof(interval) > sizeof(time)) and no other timers active and systick frequency high enough to not take ages to complete.

So you will not see it executed in default demos, it requires a special run.

Giovanni

faisal
Posts: 253
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 35 times
Been thanked: 32 times

Re: Virtual timer overflow

Postby faisal » Tue May 28, 2019 11:07 am

Giovanni wrote:Probably but it will be "conditional", executed only when the kernel is configured in the right mode: tickless and (sizeof(interval) > sizeof(time)) and no other timers active and systick frequency high enough to not take ages to complete.

So you will not see it executed in default demos, it requires a special run.

Giovanni


That works. Just as long as it's part of the standard regression test of the kernel. I'm interested in the bug being fixed, and also that the process doesn't allow it to happen again in the future.

steved
Posts: 633
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 6 times
Been thanked: 89 times

Re: Virtual timer overflow

Postby steved » Wed May 29, 2019 8:37 am

Not sure that the fix covers all situations; I saw the problem elsewhere.There are two cases to consider:
a) No virtual timers active; start one with a long delay
b) Multiple virtual timers active; shorter ones expire, until the long delay timer is the only one left.

I think the fix just covers the second case.
The first case brings you to line 134 of chvt.c:

Code: Select all

      port_timer_start_alarm(chTimeAddX(ch.vtlist.lasttime, delay));
, which is where I noticed the problem.

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Wed May 29, 2019 8:44 am

This must be a different issue with the same root cause, I will inspect all chTimeAddX() call instances.

Note that I tested your case A, it fixes it.

Giovanni

User avatar
Giovanni
Site Admin
Posts: 12313
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 594 times
Been thanked: 505 times
Contact:

Re: Virtual timer overflow

Postby Giovanni » Wed May 29, 2019 9:19 am

Hi,

Are you sure it happens in the above code?

Because:

Code: Select all


#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
      /* The delta could be too large for the physical timer to handle.*/
      if (delay > (sysinterval_t)TIME_MAX_SYSTIME) {
        delay = (sysinterval_t)TIME_MAX_SYSTIME;
      }
#endif

      /* Being the first element in the list the alarm timer is started.*/
      port_timer_start_alarm(chTimeAddX(ch.vtlist.lasttime, delay));


the "if" part seems to make the assertion in chTimeAddX() impossible. Could you make a stack trace after the assertion is triggered?

The only problem I found was in function chVTGetTimersStateI():

Code: Select all

    *timep = chTimeDiffX(chVTGetSystemTimeX(),
                         chTimeAddX(ch.vtlist.lasttime,
                                    ch.vtlist.next->delta +
                                    (sysinterval_t)CH_CFG_ST_TIMEDELTA));


has been changed in:

Code: Select all

    *timep = (ch.vtlist.next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
             chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX());


All other calls to chTimeAddX() have similar "if" guards.

Giovanni


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 1 guest