mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-20 21:43:08 +00:00
Implement recvmmsg() for Linux to reduce syscalls. (#2046)
Between 5% and 40% speed improvement on Linux, depending on system configuration and load.
This commit is contained in:
parent
50ede37a58
commit
f1019dc4ee
@ -989,6 +989,45 @@ public:
|
||||
|
||||
case ZT_PHY_SOCKET_UDP:
|
||||
if (FD_ISSET(s->sock, &rfds)) {
|
||||
#if (defined(__linux__) || defined(linux) || defined(__linux)) && defined(MSG_WAITFORONE)
|
||||
#define RECVMMSG_WINDOW_SIZE 128
|
||||
#define RECVMMSG_BUF_SIZE 1500
|
||||
iovec iovs[RECVMMSG_WINDOW_SIZE];
|
||||
uint8_t bufs[RECVMMSG_WINDOW_SIZE][RECVMMSG_BUF_SIZE];
|
||||
sockaddr_storage addrs[RECVMMSG_WINDOW_SIZE];
|
||||
memset(addrs, 0, sizeof(addrs));
|
||||
mmsghdr mm[RECVMMSG_WINDOW_SIZE];
|
||||
memset(mm, 0, sizeof(mm));
|
||||
for (int i = 0; i < RECVMMSG_WINDOW_SIZE; ++i) {
|
||||
iovs[i].iov_base = (void*)bufs[i];
|
||||
iovs[i].iov_len = RECVMMSG_BUF_SIZE;
|
||||
mm[i].msg_hdr.msg_name = (void*)&(addrs[i]);
|
||||
mm[i].msg_hdr.msg_iov = &(iovs[i]);
|
||||
mm[i].msg_hdr.msg_iovlen = 1;
|
||||
}
|
||||
for (int k = 0; k < 1024; ++k) {
|
||||
for (int i = 0; i < RECVMMSG_WINDOW_SIZE; ++i) {
|
||||
mm[i].msg_hdr.msg_namelen = sizeof(sockaddr_storage);
|
||||
mm[i].msg_len = 0;
|
||||
}
|
||||
int received_count = recvmmsg(s->sock, mm, RECVMMSG_WINDOW_SIZE, MSG_WAITFORONE, nullptr);
|
||||
if (received_count > 0) {
|
||||
for (int i = 0; i < received_count; ++i) {
|
||||
long n = (long)mm[i].msg_len;
|
||||
if (n > 0) {
|
||||
try {
|
||||
_handler->phyOnDatagram((PhySocket*)&(*s), &(s->uptr), (const struct sockaddr*)&(s->saddr), (const struct sockaddr*)&(addrs[i]), bufs[i], (unsigned long)n);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int k = 0; k < 1024; ++k) {
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
socklen_t slen = sizeof(ss);
|
||||
@ -996,10 +1035,14 @@ public:
|
||||
if (n > 0) {
|
||||
try {
|
||||
_handler->phyOnDatagram((PhySocket*)&(*s), &(s->uptr), (const struct sockaddr*)&(s->saddr), (const struct sockaddr*)&ss, (void*)buf, (unsigned long)n);
|
||||
} catch ( ... ) {}
|
||||
} else if (n < 0)
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
else if (n < 0)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user