Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions sys/include/net/gnrc/priority_pktqueue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (C) 2015 Daniel Krebs
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @{
* @defgroup net_gnrc_priority_pktqueue Priority packet queue
* @ingroup net_gnrc
* @file
* @brief Wrapper for priority_queue that holds gnrc_pktsnip_t* and is
* aware of it's length.
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
* @}
*/

#ifndef GNRC_PRIORITY_PKTQUEUE_H
#define GNRC_PRIORITY_PKTQUEUE_H

#include <stdint.h>
#include <priority_queue.h>
#include <net/gnrc/pkt.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief data type for gnrc priority packet queue nodes
*/
typedef struct gnrc_priority_pktqueue_node {
struct gnrc_priority_pktqueue_node *next; /**< next queue node */
uint32_t priority; /**< queue node priority */
gnrc_pktsnip_t *pkt; /**< queue node data */
} gnrc_priority_pktqueue_node_t;

/**
* @brief data type for gnrc priority packet queues
*/
typedef priority_queue_t gnrc_priority_pktqueue_t;

/**
* @brief Static initializer for gnrc_priority_pktqueue_node_t.
*/
#define PRIORITY_PKTQUEUE_NODE_INIT(priority, pkt) { NULL, priority, pkt }

/**
* @brief Static initializer for gnrc_priority_pktqueue_t.
*/
#define PRIORITY_PKTQUEUE_INIT { NULL }

/**
* @brief Initialize a gnrc priority packet queue node object.
*
* @param[out] node
* pre-allocated gnrc_priority_pktqueue_node_t object, must not be NULL.
* @param[in] priority
* the priority of the gnrc packet snip
* @param[in] pkt
* the gnrc packet snip
*/
static inline void gnrc_priority_pktqueue_node_init(gnrc_priority_pktqueue_node_t *node,
uint32_t priority,
gnrc_pktsnip_t *pkt)
{
node->next = NULL;
node->priority = priority;
node->pkt = pkt;
}

/**
* @brief Initialize a gnrc priority packet queue object.
*
* @param[out] queue
* pre-allocated gnrc_priority_pktqueue_t object, must not be NULL.
*/
static inline void gnrc_priority_pktqueue_init(gnrc_priority_pktqueue_t *queue)
{
gnrc_priority_pktqueue_t qn = PRIORITY_PKTQUEUE_INIT;
*queue = qn;
}

/**
* @brief Get the length information of a gnrc priority packet queue object.
*
* @param[in] queue
* pre-allocated gnrc_priority_pktqueue_t object, must not be NULL.
* @return the length of @p queue
*/
uint32_t gnrc_priority_pktqueue_length(gnrc_priority_pktqueue_t *queue);

/**
* @brief flush the gnrc priority packet queue
*
* @param[out] queue the gnrc priority packet queue, must not be NULL
*/
void gnrc_priority_pktqueue_flush(gnrc_priority_pktqueue_t* queue);

/**
* @brief Get first element and remove it from @p queue
*
* @param[out] queue the gnrc priority packet queue, may not be NULL
*
* @return the old head
*/
gnrc_pktsnip_t* gnrc_priority_pktqueue_pop(gnrc_priority_pktqueue_t* queue);

/**
* @brief Get first element from @p queue without removing
*
* @param[in] queue the gnrc priority packet queue, may not be NULL
*
* @return the head of @p queue
*/
gnrc_pktsnip_t* gnrc_priority_pktqueue_head(gnrc_priority_pktqueue_t* queue);

/**
* @brief add @p node into @p queue based on its priority
*
* @param[in,out] queue the gnrc priority packet queue, must not be NULL
* @param[in] node the node to add.
*/
void gnrc_priority_pktqueue_push(gnrc_priority_pktqueue_t* queue,
gnrc_priority_pktqueue_node_t *node);

#ifdef __cplusplus
}
#endif

#endif /* GNRC_PRIORITY_PKTQUEUE_H */
3 changes: 3 additions & 0 deletions sys/net/gnrc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ endif
ifneq (,$(filter gnrc_pktbuf_static,$(USEMODULE)))
DIRS += pktbuf_static
endif
ifneq (,$(filter gnrc_priority_pktqueue,$(USEMODULE)))
DIRS += priority_pktqueue
endif
ifneq (,$(filter gnrc_pktdump,$(USEMODULE)))
DIRS += pktdump
endif
Expand Down
3 changes: 3 additions & 0 deletions sys/net/gnrc/priority_pktqueue/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = gnrc_priority_pktqueue

include $(RIOTBASE)/Makefile.base
103 changes: 103 additions & 0 deletions sys/net/gnrc/priority_pktqueue/priority_pktqueue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2015 Daniel Krebs
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @{
* @defgroup net_gnrc_priority_pktqueue Priority packet queue
* @ingroup net_gnrc
* @file
* @brief Wrapper for priority_queue that holds gnrc_pktsnip_t* and is
* aware of it's length.
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
* @}
*/

#include "net/gnrc/pktbuf.h"
#include <net/gnrc/priority_pktqueue.h>

/******************************************************************************/

static inline void _free_node(gnrc_priority_pktqueue_node_t *node)
{
assert(node != NULL);

priority_queue_node_init((priority_queue_node_t *)node);
}

/******************************************************************************/

gnrc_pktsnip_t* gnrc_priority_pktqueue_pop(gnrc_priority_pktqueue_t* queue)
{
if(!queue || (gnrc_priority_pktqueue_length(queue) == 0)){
return NULL;
}
priority_queue_node_t *head = priority_queue_remove_head(queue);
gnrc_pktsnip_t* pkt = (gnrc_pktsnip_t*) head->data;
_free_node((gnrc_priority_pktqueue_node_t *)head);
return pkt;
}

/******************************************************************************/

gnrc_pktsnip_t* gnrc_priority_pktqueue_head(gnrc_priority_pktqueue_t* queue)
{
if(!queue || (gnrc_priority_pktqueue_length(queue) == 0)){
return NULL;
}
return (gnrc_pktsnip_t *)queue->first->data;
}
/******************************************************************************/

void gnrc_priority_pktqueue_push(gnrc_priority_pktqueue_t* queue,
gnrc_priority_pktqueue_node_t *node)
{
assert(queue != NULL);
assert(node != NULL);
assert(node->pkt != NULL);
assert(sizeof(unsigned int) == sizeof(gnrc_pktsnip_t*));

priority_queue_add(queue, (priority_queue_node_t *)node);
}

/******************************************************************************/

void gnrc_priority_pktqueue_flush(gnrc_priority_pktqueue_t* queue)
{
assert(queue != NULL);

if(gnrc_priority_pktqueue_length(queue) == 0){
return;
}
gnrc_priority_pktqueue_node_t* node;
while( (node = (gnrc_priority_pktqueue_node_t *)priority_queue_remove_head(queue)) )
{
gnrc_pktbuf_release(node->pkt);
_free_node(node);
}
}

/******************************************************************************/
uint32_t gnrc_priority_pktqueue_length(gnrc_priority_pktqueue_t *queue)
{
assert(queue != NULL);

uint32_t length = 0;
priority_queue_node_t *node = queue->first;
if(!node){
return length;
}

length ++;
while(node->next!=NULL){
length ++;
node = node->next;
}
return length;
}
1 change: 1 addition & 0 deletions tests/unittests/tests-priority_pktqueue/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
1 change: 1 addition & 0 deletions tests/unittests/tests-priority_pktqueue/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
USEMODULE += gnrc_priority_pktqueue
Loading