Skip to content

Conversation

zhuoshuguo
Copy link
Contributor

@zhuoshuguo zhuoshuguo commented Oct 14, 2016

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.

* @{
* @ingroup net_gnrc_mac
* @file
* @brief Wrapper for priority_queue that holds gnrc_pktsnip_t* and is
Copy link
Member

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?

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Member

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.

@miri64 miri64 self-assigned this Oct 16, 2016
@miri64 miri64 added Area: network Area: Networking Type: new feature The issue requests / The PR implemements a new feature for RIOT GNRC labels Oct 16, 2016
packet_queue_node_t* buffer;
size_t buffer_size;
} packet_queue_t;

Copy link
Contributor Author

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?

Copy link
Member

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?

Copy link
Contributor Author

@zhuoshuguo zhuoshuguo Oct 17, 2016

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.

Copy link
Member

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 ;-).

Copy link
Contributor Author

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. :-)

Copy link
Contributor Author

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?

Copy link
Member

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)

Copy link
Contributor Author

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.

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch from 2e37a41 to 55d6818 Compare October 17, 2016 13:30
@zhuoshuguo zhuoshuguo changed the title gnrc: Add packet queue module to gnrc mac gnrc: Add priority packet queue module to gnrc Oct 17, 2016
@zhuoshuguo
Copy link
Contributor Author

@miri64 Updated.

@@ -0,0 +1,68 @@
/*
Copy link
Member

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
Copy link
Member

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;
Copy link
Member

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.

Copy link
Member

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)

Copy link
Contributor Author

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..

Copy link
Member

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... ^^

Copy link
Contributor Author

@zhuoshuguo zhuoshuguo Oct 17, 2016

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[],
Copy link
Member

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...

Copy link
Contributor Author

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? :-)

Copy link
Contributor Author

@zhuoshuguo zhuoshuguo Oct 17, 2016

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?

Copy link
Member

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.

Copy link
Contributor Author

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.

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch from 55d6818 to cf3b7da Compare October 19, 2016 08:04
priority_queue_t queue;
packet_queue_node_t* buffer;
size_t buffer_size;
} gnrc_priority_pktqueue_t;
Copy link
Contributor Author

@zhuoshuguo zhuoshuguo Oct 19, 2016

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? :-)

Copy link
Member

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,
Copy link
Member

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)
Copy link
Member

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;
Copy link
Member

Choose a reason for hiding this comment

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

Indentation

Copy link
Contributor Author

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? :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@miri64 ping

Copy link
Member

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 😄

Copy link
Contributor Author

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))
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@zhuoshuguo zhuoshuguo Oct 21, 2016

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?

Copy link
Member

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))
Copy link
Member

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)
Copy link
Member

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)) )
Copy link
Member

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.

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch 2 times, most recently from 04fa627 to dd96570 Compare October 24, 2016 11:36
@zhuoshuguo
Copy link
Contributor Author

@miri64 can you give some tips about how to run the unittests locally (maybe on the samr21 boards?) Thus to evaluate the unittests codes written. Thanks.

@miri64
Copy link
Member

miri64 commented Oct 24, 2016

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.

@zhuoshuguo
Copy link
Contributor Author

@miri64 Thanks!

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch 3 times, most recently from a24527a to 2c09a67 Compare October 25, 2016 16:20
@zhuoshuguo
Copy link
Contributor Author

@miri64 Updated, corrected style and added unittests.

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.

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);
Copy link
Member

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?

Copy link
Contributor Author

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);

Copy link
Member

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.

@zhuoshuguo
Copy link
Contributor Author

@miri64 sorry, I tried to be more careful when building tests. Will reduce assertions.

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch from 2c09a67 to 7b941a6 Compare October 26, 2016 11:48
@zhuoshuguo
Copy link
Contributor Author

Updated.

@miri64 miri64 added this to the Release 2016.10 milestone Oct 31, 2016
@miri64
Copy link
Member

miri64 commented Oct 31, 2016

Let's try to get this into the release.

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.

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)
Copy link
Member

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);
Copy link
Member

Choose a reason for hiding this comment

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

Style: please fix indentation

@zhuoshuguo zhuoshuguo force-pushed the add_packet_queue_module_to_gnrc_mac branch from 7b941a6 to 0ebe2a0 Compare October 31, 2016 15:55
@zhuoshuguo
Copy link
Contributor Author

@miri64 Fixed style and squashed commits. :-)

@miri64 miri64 added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Oct 31, 2016
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.

ACK and go when Travis is happy

@miri64 miri64 merged commit 6dac4bd into RIOT-OS:master Nov 1, 2016
@miri64
Copy link
Member

miri64 commented Nov 1, 2016

Congrats on your first feature PR! :-)

@kYc0o
Copy link
Contributor

kYc0o commented Nov 1, 2016

Congrats Shuguo! ;-) (@miri64 it wasn't Murdock who helped? :P )

@zhuoshuguo
Copy link
Contributor Author

@miri64 @kYc0o Thanks a lot for your help! :-)

@daniel-k
Copy link
Member

daniel-k commented Nov 2, 2016

Congrats from my side too! And thanks for messing with my code 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR 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