-
Notifications
You must be signed in to change notification settings - Fork 2.1k
gnrc: Add priority packet queue module to gnrc #5950
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
gnrc: Add priority packet queue module to gnrc #5950
Conversation
* @{ | ||
* @ingroup net_gnrc_mac | ||
* @file | ||
* @brief Wrapper for priority_queue that holds gnrc_pktsnip_t* and is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with gnrc_pktqueue that you introduce another packet queue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daniel-k Can you help explain here? I remember, as you have stated somewhere, was it first due to the unawareness of "gnrc_pktqueue " when creating the packet queue module for Lw-MAC, or does it due to that we want the queue to be aware of its length?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then the preferred way would be to expand the gnrc_pktqueue
module not write your own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help explain here? I remember, as you have stated somewhere, was it first due to the unawareness of "gnrc_pktqueue " when creating the packet queue module for Lw-MAC
Yes, that's right.
or does it due to that we want the queue to be aware of its length?
This definetely helps during runtime, but the queues should be quite small anyway.
All in all my packet queue implementation was something I was planning to refactor and maybe merge with the existing one, so in general I'm with @miri64.
packet_queue_node_t* buffer; | ||
size_t buffer_size; | ||
} packet_queue_t; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, @miri64 , I think the packet_queue introduced here is more attached to the priority_queue but not gnrc_pktqueue, since the packet_queue_t here support priority while gnrc_pktqueue does not. So, it is a more wrapper to priority_queue.
Also, do you think we can leave this issue here and currently only use it in MAC layer, and solve it (i.e., extand gnrc_pktqueue or priority_queue and delete this new packet_queue module) after the merge of Lw-MAC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! Though it is documented that gnrc_pktqueue
is based on priority queue it isn't. Will fix. So maybe (since this might not just be of interest to MAC) rename this module gnrc_priority_pktqueue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this packet_queue module here is still not ready for universal usage yet. Just my opinion. This is because, if you check the packet_queue_t structure above, it contains a buffer (type of packet_queue_node_t, which is actually priority_queue_node_t). This means that you need to define a packet buffer first for holding your packets before using queue management.
In short, the queue management module here relies on a predefined packet buffer which is assumed to be created and initiated before start using the queue management provided here. check the example case in Lw-MAC: buffer define, init function and init before use.
So, currently it is more MAC-oriented... and I tend to revise it after the merge of the Lw-MAC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that because of this the contrary is the case: it is even more suitable for general use. Compare e.g. the packet buffer which only allows for one central array to be the packet buffer. The implementation here can however be cleaned up a little bit. That I agree. But I still don't see any reason why this makes it dependent on MAC ;-).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, with your support, I will update it now, move it out of gnrc_mac. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, @miri64 where do you think I can place this gnrc_priority_pktqueue.c
, in /RIOT/sys/net/gnrc/pkt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's its own module, so I would suggest to pout it into sys/net/gnrc/priority_pktqueue
(you need to add a makefile to that directory and also need to update sys/net/gnrc/Makefile
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I see. Will do it now.
2e37a41
to
55d6818
Compare
@miri64 Updated. |
@@ -0,0 +1,68 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove the leading gnrc_
in the headers name. It is already reflected in the sub-directory gnrc/
|
||
/** | ||
* @{ | ||
* @ingroup net_gnrc_oriority_pktqueue Priority packet queue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @defgroup net_gnrc_priority_pktqueue Priority packet queue
* @ingroup net_gnrc
uint32_t length; | ||
packet_queue_node_t* buffer; | ||
size_t buffer_size; | ||
} packet_queue_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please harmonize the type's name with the modules name? Also I think that having both length
and buffer_size
is superfluous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(e.g gnrc_priority_pktqueue_t
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the buffer_size
reflects the central buffer size which is needed when initializing the queue, while the length is the queue's length..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah... I would store neither in this struct... ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, what is why I thought it may not be ready for general usage..:-)
uint32_t priority); | ||
|
||
void packet_queue_init(packet_queue_t* q, | ||
packet_queue_node_t buffer[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it, I don't see any benefit in doing this way. A user of this API can just as well have their buffer stored somewhere instead of wasting up to 8 byte on buffer and buffer size...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, what do you suggest now? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@miri64 so I still keep this in my gnrc_mac
module and revise it in the future? Just put this issue aside?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, let's find some API we both are happy with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will try to rework this PR.
55d6818
to
cf3b7da
Compare
priority_queue_t queue; | ||
packet_queue_node_t* buffer; | ||
size_t buffer_size; | ||
} gnrc_priority_pktqueue_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@miri64 Updated, deleted length
and updated the method for getting the queue length.
But I still keep the buffer_size
parameter for queue initialization, since I couldn't think up a way to initialize the queue without it, i.e., how to be aware of the buffer size if we only pass in the *buffer
when doing initialization.
Do you have some tips for this? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See zhuoshuguo#1 for my proposal.
|
||
#define PRIORITY_PKTQUEUE_NODE_INIT(priority, pkt) { NULL, priority, pkt } | ||
|
||
static inline void priority_pktqueue_node_init(gnrc_priority_pktqueue_node_t *node, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please prefix these functions and macros with gnrc_
. I know I introduced some of these, but I tried to keep style with the current status of this PR.
*q = qn; | ||
} | ||
|
||
static inline uint32_t priority_pktqueue_length(gnrc_priority_pktqueue_t *q) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is quiet big for an inline function. Please un-inline.
|
||
static inline uint32_t priority_pktqueue_length(gnrc_priority_pktqueue_t *q) | ||
{ | ||
uint32_t length = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to ensure, you mean I should use four spaces here? instead of a tab, right? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@miri64 ping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry thought I already replied 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! :-)
|
||
gnrc_pktsnip_t* priority_pktqueue_pop(gnrc_priority_pktqueue_t* q) | ||
{ | ||
if(!q || (priority_pktqueue_length(q) == 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, I should add a braces right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
|
||
gnrc_pktsnip_t* priority_pktqueue_head(gnrc_priority_pktqueue_t* q) | ||
{ | ||
if(!q || (priority_pktqueue_length(q) == 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
void priority_pktqueue_flush(gnrc_priority_pktqueue_t* q) | ||
{ | ||
if(priority_pktqueue_length(q) == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return; | ||
|
||
gnrc_priority_pktqueue_node_t* node; | ||
while( (node = (gnrc_priority_pktqueue_node_t *)priority_queue_remove_head(q)) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: Please put the brace on the same line as the while and remove the whitespaces between the parans.
04fa627
to
dd96570
Compare
Sure, just follow the steps in https://github.com/RIOT-OS/RIOT/blob/master/tests/unittests/README.md. To build for a dedicated board you need to define it as an environment variable variable (as you normally would do with other applications) and flash in between build and term step. |
@miri64 Thanks! |
a24527a
to
2c09a67
Compare
@miri64 Updated, corrected style and added unittests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the assertion in the unittests are far to excessive. oO but the line below caught my eye in particular
res = gnrc_priority_pktqueue_pop(&pkt_queue); | ||
|
||
TEST_ASSERT(res == &pkt2); | ||
TEST_ASSERT_EQUAL_INT(0,((priority_queue_node_t *)&elem2)->data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler flags for the boards do not allow for such type-punning. Also, why is this line even here? And shouldn't this be the address value of pkt2
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this assert since, inside gnrc_priority_pktqueue_pop
, it will call _free_node()
in which priority_queue_node_init()
will be further called to initialize the popped elem
. So I want to check the result of initialization of elem
. I checked that priority_queue_node_init()
will set the data
to 0
, that's why I did this kind of assert..
But, you are right, I should do this more concisely by TEST_ASSERT_NULL(elem2.pkt);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, and yes: TEST_ASSERT_NULL()
should is the better option.
@miri64 sorry, I tried to be more careful when building tests. Will reduce assertions. |
2c09a67
to
7b941a6
Compare
Updated. |
Let's try to get this into the release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last minor request.
*/ | ||
static inline void gnrc_priority_pktqueue_node_init(gnrc_priority_pktqueue_node_t *node, | ||
uint32_t priority, | ||
gnrc_pktsnip_t *pkt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style, please fix indentation
* @param[in] node the node to add. | ||
*/ | ||
void gnrc_priority_pktqueue_push(gnrc_priority_pktqueue_t* queue, | ||
gnrc_priority_pktqueue_node_t *node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: please fix indentation
7b941a6
to
0ebe2a0
Compare
@miri64 Fixed style and squashed commits. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK and go when Travis is happy
Congrats on your first feature PR! :-) |
Congrats Shuguo! ;-) (@miri64 it wasn't Murdock who helped? :P ) |
Congrats from my side too! And thanks for messing with my code 😃 |
This PR aim to priority packet queue module to gnrc.
PS: this module here is extracted/sorted from the packet queue management block of Lw-MAC.