Skip to content

Commit

Permalink
Merge pull request contiki-os#648 from cetic/pr-csma-fixes
Browse files Browse the repository at this point in the history
High throughput fixes for csma and sixlowpan
  • Loading branch information
Nicolas Tsiftes committed Oct 21, 2014
2 parents 10d4446 + 7cbd59d commit 6fb7dd2
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 43 deletions.
13 changes: 13 additions & 0 deletions core/lib/memb.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,18 @@ memb_inmemb(struct memb *m, void *ptr)
(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;
}
/** @} */
1 change: 1 addition & 0 deletions core/lib/memb.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ char memb_free(struct memb *m, void *ptr);

int memb_inmemb(struct memb *m, void *ptr);

int memb_numfree(struct memb *m);

/** @} */
/** @} */
Expand Down
7 changes: 7 additions & 0 deletions core/net/ipv6/sicslowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,13 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* 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);

Expand Down
101 changes: 59 additions & 42 deletions core/net/mac/csma.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ struct neighbor_queue {
#define CSMA_MAX_NEIGHBOR_QUEUES 2
#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
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
Expand Down Expand Up @@ -173,8 +180,8 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p)
queuebuf_free(p->buf);
memb_free(&metadata_memb, p->ptr);
memb_free(&packet_memb, p);
PRINTF("csma: free_queued_packet, queue length %d\n",
list_length(n->queued_packet_list));
PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
if(list_head(n->queued_packet_list) != NULL) {
/* There is a next packet. We reset current tx information */
n->transmissions = 0;
Expand Down Expand Up @@ -298,7 +305,11 @@ packet_sent(void *ptr, int status, int num_transmissions)
free_packet(n, q);
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));
}
}
/*---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -344,47 +355,53 @@ send_packet(mac_callback_t sent, void *ptr)

if(n != NULL) {
/* Add packet to the neighbor's queue */
q = memb_alloc(&packet_memb);
if(q != NULL) {
q->ptr = memb_alloc(&metadata_memb);
if(q->ptr != NULL) {
q->buf = queuebuf_new_from_packetbuf();
if(q->buf != NULL) {
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
/* Neighbor and packet successfully allocated */
if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
/* Use default configuration for max transmissions */
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
} else {
metadata->max_transmissions =
packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
}
metadata->sent = sent;
metadata->cptr = ptr;

if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q);
} else {
list_add(n->queued_packet_list, q);
}

/* If q is the first packet in the neighbor's queue, send asap */
if(list_head(n->queued_packet_list) == q) {
ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
}
return;
}
memb_free(&metadata_memb, q->ptr);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
q = memb_alloc(&packet_memb);
if(q != NULL) {
q->ptr = memb_alloc(&metadata_memb);
if(q->ptr != NULL) {
q->buf = queuebuf_new_from_packetbuf();
if(q->buf != NULL) {
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
/* Neighbor and packet successfully allocated */
if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
/* Use default configuration for max transmissions */
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
} else {
metadata->max_transmissions =
packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
}
metadata->sent = sent;
metadata->cptr = ptr;

if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q);
} else {
list_add(n->queued_packet_list, q);
}

PRINTF("csma: send_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
/* If q is the first packet in the neighbor's queue, send asap */
if(list_head(n->queued_packet_list) == q) {
ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
}
return;
}
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);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
/* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) {
list_remove(neighbor_list, n);
memb_free(&neighbor_memb, n);
/* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) {
list_remove(neighbor_list, n);
memb_free(&neighbor_memb, n);
}
} else {
PRINTF("csma: Neighbor queue full\n");
}
PRINTF("csma: could not allocate packet, dropping packet\n");
} else {
Expand Down
10 changes: 10 additions & 0 deletions core/net/queuebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ queuebuf_init(void)
#endif /* QUEUEBUF_STATS */
}
/*---------------------------------------------------------------------------*/
int
queuebuf_numfree(void)
{
if(packetbuf_is_reference()) {
return memb_numfree(&refbufmem);
} else {
return memb_numfree(&bufmem);
}
}
/*---------------------------------------------------------------------------*/
#if QUEUEBUF_DEBUG
struct queuebuf *
queuebuf_new_from_packetbuf_debug(const char *file, int line)
Expand Down
4 changes: 3 additions & 1 deletion core/net/queuebuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ packetbuf_attr_t queuebuf_attr(struct queuebuf *b, uint8_t type);

void queuebuf_debug_print(void);

#endif /* QUEUEBUF_H_ */
int queuebuf_numfree(void);

#endif /* __QUEUEBUF_H__ */

/** @} */
/** @} */

0 comments on commit 6fb7dd2

Please sign in to comment.