Merge pull request #648 from cetic/pr-csma-fixes

High throughput fixes for csma and sixlowpan
This commit is contained in:
Nicolas Tsiftes 2014-10-21 12:17:03 +02:00
commit 6fb7dd238e
6 changed files with 91 additions and 41 deletions

View file

@ -107,5 +107,18 @@ memb_inmemb(struct memb *m, void *ptr)
(char *)ptr < (char *)m->mem + (m->num * m->size); (char *)ptr < (char *)m->mem + (m->num * m->size);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int
memb_numfree(struct memb *m)
{
int i;
int num_free = 0;
for(i = 0; i < m->num; ++i) {
if(m->count[i] == 0) {
++num_free;
}
}
return num_free;
}
/** @} */ /** @} */

View file

@ -130,6 +130,7 @@ char memb_free(struct memb *m, void *ptr);
int memb_inmemb(struct memb *m, void *ptr); int memb_inmemb(struct memb *m, void *ptr);
int memb_numfree(struct memb *m);
/** @} */ /** @} */
/** @} */ /** @} */

View file

@ -1458,6 +1458,13 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers. * IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch. * The following fragments contain only the fragn dispatch.
*/ */
int estimated_fragments = ((int)uip_len) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
int freebuf = queuebuf_numfree() - 1;
PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {
PRINTFO("Dropping packet, not enough free bufs\n");
return 0;
}
PRINTFO("Fragmentation sending packet len %d\n", uip_len); PRINTFO("Fragmentation sending packet len %d\n", uip_len);

View file

@ -108,6 +108,13 @@ struct neighbor_queue {
#define CSMA_MAX_NEIGHBOR_QUEUES 2 #define CSMA_MAX_NEIGHBOR_QUEUES 2
#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */ #endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */
/* The maximum number of pending packet per neighbor */
#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#else
#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS
#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */
#define MAX_QUEUED_PACKETS QUEUEBUF_NUM #define MAX_QUEUED_PACKETS QUEUEBUF_NUM
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES); MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS); MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
@ -173,8 +180,8 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p)
queuebuf_free(p->buf); queuebuf_free(p->buf);
memb_free(&metadata_memb, p->ptr); memb_free(&metadata_memb, p->ptr);
memb_free(&packet_memb, p); memb_free(&packet_memb, p);
PRINTF("csma: free_queued_packet, queue length %d\n", PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list)); list_length(n->queued_packet_list), memb_numfree(&packet_memb));
if(list_head(n->queued_packet_list) != NULL) { if(list_head(n->queued_packet_list) != NULL) {
/* There is a next packet. We reset current tx information */ /* There is a next packet. We reset current tx information */
n->transmissions = 0; n->transmissions = 0;
@ -298,7 +305,11 @@ packet_sent(void *ptr, int status, int num_transmissions)
free_packet(n, q); free_packet(n, q);
mac_call_sent_callback(sent, cptr, status, num_tx); mac_call_sent_callback(sent, cptr, status, num_tx);
} }
} else {
PRINTF("csma: no metadata\n");
} }
} else {
PRINTF("csma: seqno %d not found\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -344,47 +355,53 @@ send_packet(mac_callback_t sent, void *ptr)
if(n != NULL) { if(n != NULL) {
/* Add packet to the neighbor's queue */ /* Add packet to the neighbor's queue */
q = memb_alloc(&packet_memb); if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
if(q != NULL) { q = memb_alloc(&packet_memb);
q->ptr = memb_alloc(&metadata_memb); if(q != NULL) {
if(q->ptr != NULL) { q->ptr = memb_alloc(&metadata_memb);
q->buf = queuebuf_new_from_packetbuf(); if(q->ptr != NULL) {
if(q->buf != NULL) { q->buf = queuebuf_new_from_packetbuf();
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; if(q->buf != NULL) {
/* Neighbor and packet successfully allocated */ struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { /* Neighbor and packet successfully allocated */
/* Use default configuration for max transmissions */ if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; /* Use default configuration for max transmissions */
} else { metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
metadata->max_transmissions = } else {
packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); metadata->max_transmissions =
} packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
metadata->sent = sent; }
metadata->cptr = ptr; metadata->sent = sent;
metadata->cptr = ptr;
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) { PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q); list_push(n->queued_packet_list, q);
} else { } else {
list_add(n->queued_packet_list, q); list_add(n->queued_packet_list, q);
} }
/* If q is the first packet in the neighbor's queue, send asap */ PRINTF("csma: send_packet, queue length %d, free packets %d\n",
if(list_head(n->queued_packet_list) == q) { list_length(n->queued_packet_list), memb_numfree(&packet_memb));
ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n); /* If q is the first packet in the neighbor's queue, send asap */
} if(list_head(n->queued_packet_list) == q) {
return; ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
} }
memb_free(&metadata_memb, q->ptr); return;
PRINTF("csma: could not allocate queuebuf, dropping packet\n"); }
memb_free(&metadata_memb, q->ptr);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
memb_free(&packet_memb, q);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
} }
memb_free(&packet_memb, q); /* The packet allocation failed. Remove and free neighbor entry if empty. */
PRINTF("csma: could not allocate queuebuf, dropping packet\n"); if(list_length(n->queued_packet_list) == 0) {
} list_remove(neighbor_list, n);
/* The packet allocation failed. Remove and free neighbor entry if empty. */ memb_free(&neighbor_memb, n);
if(list_length(n->queued_packet_list) == 0) { }
list_remove(neighbor_list, n); } else {
memb_free(&neighbor_memb, n); PRINTF("csma: Neighbor queue full\n");
} }
PRINTF("csma: could not allocate packet, dropping packet\n"); PRINTF("csma: could not allocate packet, dropping packet\n");
} else { } else {

View file

@ -307,6 +307,16 @@ queuebuf_init(void)
#endif /* QUEUEBUF_STATS */ #endif /* QUEUEBUF_STATS */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int
queuebuf_numfree(void)
{
if(packetbuf_is_reference()) {
return memb_numfree(&refbufmem);
} else {
return memb_numfree(&bufmem);
}
}
/*---------------------------------------------------------------------------*/
#if QUEUEBUF_DEBUG #if QUEUEBUF_DEBUG
struct queuebuf * struct queuebuf *
queuebuf_new_from_packetbuf_debug(const char *file, int line) queuebuf_new_from_packetbuf_debug(const char *file, int line)

View file

@ -109,7 +109,9 @@ packetbuf_attr_t queuebuf_attr(struct queuebuf *b, uint8_t type);
void queuebuf_debug_print(void); void queuebuf_debug_print(void);
#endif /* QUEUEBUF_H_ */ int queuebuf_numfree(void);
#endif /* __QUEUEBUF_H__ */
/** @} */ /** @} */
/** @} */ /** @} */