extmod/modlwip: Use Nagle algorithm and add support for TCP_NODELAY.
This adds support to use the Nagle algorithm implemented already in lwIP to determine when TCP data should be sent. As currently written, MicroPython will only create packets if there is <25% remaining in the send buffer. Using it, sending a small message of ~50 bytes will not trigger output of the message on the network. So it will remained queued until the TCP interval timer expires, which can be up to 500ms. Using Nagle's algorithm, the first write, no matter how small, will generate a packet on the network. And sending lots of data still makes efficient use of the link. In addition to this, an application designer may choose to always create packets for every write by setting the TCP_NODELAY socket option. That's also implemented in this commit.
This commit is contained in:
committed by
Damien George
parent
d532f960a4
commit
b1e9602702
@@ -69,6 +69,8 @@
|
|||||||
#define IP_ADD_MEMBERSHIP 0x400
|
#define IP_ADD_MEMBERSHIP 0x400
|
||||||
#define IP_DROP_MEMBERSHIP 0x401
|
#define IP_DROP_MEMBERSHIP 0x401
|
||||||
|
|
||||||
|
#define TCP_NODELAY TF_NODELAY
|
||||||
|
|
||||||
// For compatibilily with older lwIP versions.
|
// For compatibilily with older lwIP versions.
|
||||||
#ifndef ip_set_option
|
#ifndef ip_set_option
|
||||||
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
|
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
|
||||||
@@ -76,6 +78,12 @@
|
|||||||
#ifndef ip_reset_option
|
#ifndef ip_reset_option
|
||||||
#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
|
#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef tcp_set_flags
|
||||||
|
#define tcp_set_flags(pcb, set_flags) do { (pcb)->flags |= (set_flags); } while (0)
|
||||||
|
#endif
|
||||||
|
#ifndef tcp_clear_flags
|
||||||
|
#define tcp_clear_flags(pcb, clear_flags) do { (pcb)->flags &= ~(clear_flags); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// A port can define these hooks to provide concurrency protection
|
// A port can define these hooks to provide concurrency protection
|
||||||
#ifndef MICROPY_PY_LWIP_ENTER
|
#ifndef MICROPY_PY_LWIP_ENTER
|
||||||
@@ -742,9 +750,10 @@ static mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
|
|||||||
MICROPY_PY_LWIP_REENTER
|
MICROPY_PY_LWIP_REENTER
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the output buffer is getting full then send the data to the lower layers
|
// Use nagle algorithm to determine when to send segment buffer (can be
|
||||||
if (err == ERR_OK && tcp_sndbuf(socket->pcb.tcp) < TCP_SND_BUF / 4) {
|
// disabled with TCP_NODELAY socket option)
|
||||||
err = tcp_output(socket->pcb.tcp);
|
if (err == ERR_OK) {
|
||||||
|
err = tcp_output_nagle(socket->pcb.tcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
@@ -1440,6 +1449,17 @@ static mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// level: IPPROTO_TCP
|
||||||
|
case TCP_NODELAY: {
|
||||||
|
mp_int_t val = mp_obj_get_int(args[3]);
|
||||||
|
if (val) {
|
||||||
|
tcp_set_flags(socket->pcb.tcp, opt);
|
||||||
|
} else {
|
||||||
|
tcp_clear_flags(socket->pcb.tcp, opt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Warning: lwip.setsockopt() not implemented\n");
|
printf("Warning: lwip.setsockopt() not implemented\n");
|
||||||
}
|
}
|
||||||
@@ -1829,6 +1849,9 @@ static const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) },
|
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) },
|
{ MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_IP_DROP_MEMBERSHIP), MP_ROM_INT(IP_DROP_MEMBERSHIP) },
|
{ MP_ROM_QSTR(MP_QSTR_IP_DROP_MEMBERSHIP), MP_ROM_INT(IP_DROP_MEMBERSHIP) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(IP_PROTO_TCP) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_TCP_NODELAY), MP_ROM_INT(TCP_NODELAY) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);
|
static MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);
|
||||||
|
|||||||
Reference in New Issue
Block a user