Skip to content

Conversation

@kaspar030
Copy link
Contributor

I have this timer module lying around. It's design goals are:

  • use less state per timer
  • don't waste memory for practically useless precision

I ended up with using a single pointer and a 32bit value per timer, making it possible to have a timers that only use 8 bytes on a 32bit platform.

@kaspar030 kaspar030 added State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Type: new feature The issue requests / The PR implemements a new feature for RIOT Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR labels Oct 26, 2016
@miri64
Copy link
Member

miri64 commented Oct 26, 2016

@kaspar030 what about kaspar030#19?

@miri64
Copy link
Member

miri64 commented Oct 26, 2016

Sorry wrong link. Corrected in edit.

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

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

Some changes I already introduced in kaspar030#19

DEBUG("evtimer_add(): adding event with offset %"PRIu32"\n", event->offset);

_update_head_offset(evtimer);
_add_event_to_list((evtimer_event_t*)&evtimer->events, event);
Copy link
Member

Choose a reason for hiding this comment

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

Why the cast and why the address operator here?

evtimer->events = NULL;
}

#if ENABLE_DEBUG == 1
Copy link
Member

Choose a reason for hiding this comment

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

This requires any external caller to edit this file internally (which also causes printing of the messages above). The compile should optimize it away if it isn't called. Alternatively, put this function in another file (if you don't trust the compiler optimization).

* @brief Integer divide val by 125
*
* This function can be used to convert uint64_t microsecond times (or
* intervals) to miliseconds and store them in uint32_t variables, with up to
Copy link
Member

Choose a reason for hiding this comment

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

milliseconds


evtimer_msg_event_t *mevent;
while ((mevent = (evtimer_msg_event_t *)_get_next(evtimer))) {
msg_send_int(&mevent->msg, mevent->msg.sender_pid);
Copy link
Member

Choose a reason for hiding this comment

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

Send to sender_pid? Also: isn't this value usually uninitialized by the user?

Easy fix: see here

@zhuoshuguo
Copy link
Contributor

zhuoshuguo commented Nov 4, 2016

By playing with it, I think I found a possible bug:
I simply couldn't add the first event timeout:

    evtimer_t evtimer; 
    evtimer_msg_event_t msg_event;

    ......
    msg_event.event.next= NULL;
    msg_event.event.offset = 2000;
    msg_event.msg.type = GNRC_EVTIMEOUT_TYPE;
    msg_event.msg.content.ptr = &msg_event;
    msg_event.msg.sender_pid = gnrc_netdev2->pid;

    evtimer_init(&evtimer, evtimer_msg_handler);
    evtimer_add(&evtimer, (evtimer_event_t *)&msg_event);

Then, I checked and found that _add_event_to_list() (also _del_event_from_list()) seems to have malfunction, please see below and fix

{
uint32_t delta_sum = 0;

while (list->next) {
Copy link
Contributor

@zhuoshuguo zhuoshuguo Nov 4, 2016

Choose a reason for hiding this comment

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

Maybe list-next is wrongly placed here.

when firstly add an event, i.e., the first element of evtimer->events, which is list here, is NULL. But list->next may not be NULL, and the following execution may lead to chaos...

In my test, when adding the first event, it goes into the while loop, which I think it is not as we expected. :-)


static void _del_event_from_list(evtimer_event_t *list, evtimer_event_t *event)
{
while (list->next) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar issue here.

struct evtimer_event {
evtimer_event_t *next;
uint32_t offset;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think we can add a expired bool value into the evtimer_event_t structure, which I think should be commonly used by users? :-)
@miri64 If not, I think I will add it (expired) into my gnrc_mac timeout module which will probably be the wrapper of evtimer module.

Copy link
Member

Choose a reason for hiding this comment

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

@zhuoshuguo it's more RAM saving to implement expired as a function if you actually need it (though usually it is more advisable to just react via callback to an expired event ;-)): You could check the event list if the event is still contained.

Copy link
Contributor

Choose a reason for hiding this comment

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

@miri64 I think you are right~ 😄 Thanks!

@zhuoshuguo
Copy link
Contributor

Add checking event running/scheduled functionality (see add_check_event_sched) which I think also enables checking event expired. Should be at least useful for me. 😄

@kaspar030
Copy link
Contributor Author

Then, I checked and found that _add_event_to_list() (also _del_event_from_list()) seems to have malfunction, please see below and fix

Sorry, what was a too-quickly fix in the last commit. Both functions' logics required to get a pointer to pointer to the first list element in order to work, which I diffed out accidentaly. I've moved the pointer logic into the functions now.

@zhuoshuguo
Copy link
Contributor

@kaspar030 Sorry for my impetuous action..

@kaspar030
Copy link
Contributor Author

kaspar030 commented Nov 8, 2016 via email

@miri64 miri64 self-assigned this Nov 10, 2016
@miri64 miri64 added this to the Release 2017.01 milestone Nov 10, 2016
@miri64
Copy link
Member

miri64 commented Jan 4, 2017

@kaspar030 can you provide [edit]documentation[/edit] (and maybe even tests)? I need to use this soon-ish for NDP. Let's merge this with #6000 later on (especially since we need to overhaul IPC to use thread flags for my use-case anyways to make it useful for my context anyways :-/).

* @return (val / 125)
*/
static inline uint32_t div_u64_by_125(uint64_t val)
{
Copy link
Member

Choose a reason for hiding this comment

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

Since when do we use two spaces?

@miri64
Copy link
Member

miri64 commented Jan 6, 2017

Also, please consider kaspar030#22. This streamlines the message-based API a little bit.

@miri64
Copy link
Member

miri64 commented Jan 10, 2017

Also doesn't build atm... Will see, if I can provide a fix.

@miri64
Copy link
Member

miri64 commented Jan 11, 2017

Ah, the changes in #5608 were the problem.

@miri64
Copy link
Member

miri64 commented Jan 24, 2017

I guess we postpone then.

@miri64 miri64 modified the milestones: Release 2017.04, Release 2017.01 Jan 24, 2017
@zhuoshuguo
Copy link
Contributor

I will be also thankful if this PR will get merged soon, since my gnrc_mac's timeout module is also based on evtimer. 😄

@emmanuelsearch
Copy link
Member

emmanuelsearch commented Feb 13, 2017

@kaspar030 any news on this? What should be done in #6554 at this point concerning this PR?
Is it still WIP?
If so shall #6554 go forward without it for now?

@zhuoshuguo
Copy link
Contributor

If this PR is still WIP, I suggest we push #6554 forward without it (evtimer).

While when this PR get merged someday in the future, I will push #5949 to merge, and reflect evtimer in #6554.

@miri64
Copy link
Member

miri64 commented Mar 16, 2017

PING?

@miri64 miri64 mentioned this pull request Mar 20, 2017
@miri64
Copy link
Member

miri64 commented Mar 20, 2017

Adopted in #6767

@kaspar030
Copy link
Contributor Author

Closed in favour of 6767. Thanks for taking over!

@kaspar030 kaspar030 closed this Mar 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants