Merge pull request #648 from cetic/pr-csma-fixes
High throughput fixes for csma and sixlowpan
This commit is contained in:
commit
6fb7dd238e
|
@ -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;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
Loading…
Reference in a new issue