The recvmmsg and sendmmsg is very important for UDP stream application.
If we only use recvmsg for UDP stream, it will only copy one mtu size of data in a syscall. And recvmmsg copy as many as you want in a syscall.
So recvmmsg is more efficient,and some applications will depends on the recvmmsg and sendmmsg, eg: UDP media stream player.
Signed-off-by: Guo Ren ren_guo@c-sky.com --- include/sys/socket.h | 30 ++++++++++++++++++++++++++++ libc/inet/Makefile.in | 3 ++- libc/inet/recvmmsg.c | 8 ++++++++ libc/inet/sendmmsg.c | 8 ++++++++ libc/inet/socketcalls.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ libpthread/nptl/Makefile.in | 2 ++ 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 libc/inet/recvmmsg.c create mode 100644 libc/inet/sendmmsg.c
diff --git a/include/sys/socket.h b/include/sys/socket.h index 8642312..63dc4b9 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -97,6 +97,15 @@ typedef union { __SOCKADDR_ALLTYPES # undef __SOCKADDR_ONETYPE #endif
+#ifdef __USE_GNU +/* For `recvmmsg' and `sendmmsg'. */ +struct mmsghdr + { + struct msghdr msg_hdr; /* Actual message header. */ + unsigned int msg_len; /* Number of received or sent bytes for the + entry. */ + }; +#endif
/* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. @@ -190,6 +199,17 @@ extern ssize_t sendmsg (int __fd, const struct msghdr *__message, int __flags); libc_hidden_proto(sendmsg)
+#ifdef __USE_GNU +/* Send a VLEN messages as described by VMESSAGES to socket FD. + Returns the number of datagrams successfully written or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t sendmmsg (int __fd, struct mmsghdr *__vmessages, + size_t __vlen, int __flags); +libc_hidden_proto(sendmmsg) +#endif + /* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors.
@@ -198,6 +218,16 @@ libc_hidden_proto(sendmsg) extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); libc_hidden_proto(recvmsg)
+#ifdef __USE_GNU +/* Receive up to VLEN messages as described by VMESSAGES from socket FD. + Returns the number of messages received or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t recvmmsg (int __fd, struct mmsghdr *__vmessages, + size_t vlen, int __flags, struct timespec *__tmo); +libc_hidden_proto(recvmmsg) +#endif
/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index 332e70e..bed76c3 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -47,7 +47,8 @@ CSRC-$(UCLIBC_HAS_RESOLVER_SUPPORT) += \ socketcalls_CSRC-y += \ accept.c bind.c connect.c getpeername.c getsockname.c \ getsockopt.c listen.c recv.c recvfrom.c recvmsg.c send.c sendmsg.c \ - sendto.c setsockopt.c shutdown.c socket.c socketpair.c + sendto.c setsockopt.c shutdown.c socket.c socketpair.c \ + recvmmsg.c sendmmsg.c socketcalls_CSRC-$(UCLIBC_LINUX_SPECIFIC) += accept4.c CSRC-$(UCLIBC_HAS_SOCKET) += $(socketcalls_CSRC-y) opensock.c
diff --git a/libc/inet/recvmmsg.c b/libc/inet/recvmmsg.c new file mode 100644 index 0000000..003b5a6 --- /dev/null +++ b/libc/inet/recvmmsg.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen andersen@uclibc.org + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_recvmmsg +#include "socketcalls.c" diff --git a/libc/inet/sendmmsg.c b/libc/inet/sendmmsg.c new file mode 100644 index 0000000..f1557fe --- /dev/null +++ b/libc/inet/sendmmsg.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen andersen@uclibc.org + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_sendmmsg +#include "socketcalls.c" diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index 1fef810..cb28140 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -29,6 +29,8 @@ #define SYS_SENDMSG 16 #define SYS_RECVMSG 17 #define SYS_ACCEPT4 18 +#define SYS_RECVMMSG 19 +#define SYS_SENDMMSG 20 #endif
/* exposed on x86 since Linux commit 9dea5dc921b5f4045a18c63eb92e84dc274d17eb */ @@ -283,6 +285,30 @@ CANCELLABLE_SYSCALL(ssize_t, recvmsg, (int sockfd, struct msghdr *msg, int flags lt_libc_hidden(recvmsg) #endif
+#ifdef L_recvmmsg +static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, + int flags, struct timespec *tmo) +{ +# ifdef __NR_recvmmsg + return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); +# else + unsigned long args[5]; + + args[0] = sockfd; + args[1] = (unsigned long) msg; + args[2] = vlen; + args[3] = flags; + args[4] = (unsigned long) tmo; + return (ssize_t)__socketcall(SYS_RECVMMSG, args); +# endif +} +CANCELLABLE_SYSCALL(ssize_t, recvmmsg, + (int sockfd, struct mmsghdr *msg, size_t vlen, int flags, + struct timespec *tmo), + (sockfd, msg, vlen, flags, tmo)) +lt_libc_hidden(recvmmsg) +#endif + #ifdef L_send static ssize_t __NC(send)(int sockfd, const void *buffer, size_t len, int flags) { @@ -324,6 +350,28 @@ CANCELLABLE_SYSCALL(ssize_t, sendmsg, (int sockfd, const struct msghdr *msg, int lt_libc_hidden(sendmsg) #endif
+#ifdef L_sendmmsg +static ssize_t __NC(sendmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, + int flags) +{ +# ifdef __NR_sendmmsg + return (ssize_t)INLINE_SYSCALL(sendmmsg, 4, sockfd, msg, vlen, flags); +# else + unsigned long args[4]; + + args[0] = sockfd; + args[1] = (unsigned long) msg; + args[2] = vlen; + args[3] = flags; + return (ssize_t)__socketcall(SYS_SENDMMSG, args); +# endif +} +CANCELLABLE_SYSCALL(ssize_t, sendmmsg, + (int sockfd, struct mmsghdr *msg, size_t vlen, int flags), + (sockfd, msg, vlen, flags)) +lt_libc_hidden(sendmmsg) +#endif + #ifdef L_sendto ssize_t __NC(sendto)(int sockfd, const void *buffer, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) diff --git a/libpthread/nptl/Makefile.in b/libpthread/nptl/Makefile.in index 068eee4..a2f30ac 100644 --- a/libpthread/nptl/Makefile.in +++ b/libpthread/nptl/Makefile.in @@ -166,11 +166,13 @@ CFLAGS-readv.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recv.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recvfrom.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recvmsg.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-__rt_sigtimedwait.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-__rt_sigwaitinfo.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-send.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sendmsg.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sendto.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sigpause.c = -fexceptions CFLAGS-sigsuspend.c = -fexceptions -fasynchronous-unwind-tables
This is the right patch, and forget previous wrong patch.
----------- Guo Ren, Software Engineer, C-SKY 3 XiDoumen Rd,BldgA,15F,Hangzhou,China P.C: 310012T: +86 13376814331M: ren_guo@c-sky.com http://www.c-sky.comhttps://c-sky.github.io
------------------------------------------------------------------From:郭任 ren_guo@c-sky.comTime:2017 Sep 27 (Wed) 13:34To:devel-uclibc-ng devel@uclibc-ng.orgCc:wbx wbx@uclibc-ng.org; 郭任 ren_guo@c-sky.comSubject:[PATCH] recvmmsg/sendmmsg: add recvmmsg sendmmsg support. The recvmmsg and sendmmsg is very important for UDP stream application.
If we only use recvmsg for UDP stream, it will only copy one mtu size of data in a syscall. And recvmmsg copy as many as you want in a syscall.
So recvmmsg is more efficient,and some applications will depends on the recvmmsg and sendmmsg, eg: UDP media stream player.
Signed-off-by: Guo Ren ren_guo@c-sky.com --- include/sys/socket.h | 30 ++++++++++++++++++++++++++++ libc/inet/Makefile.in | 3 ++- libc/inet/recvmmsg.c | 8 ++++++++ libc/inet/sendmmsg.c | 8 ++++++++ libc/inet/socketcalls.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ libpthread/nptl/Makefile.in | 2 ++ 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 libc/inet/recvmmsg.c create mode 100644 libc/inet/sendmmsg.c
diff --git a/include/sys/socket.h b/include/sys/socket.h index 8642312..63dc4b9 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -97,6 +97,15 @@ typedef union { __SOCKADDR_ALLTYPES # undef __SOCKADDR_ONETYPE #endif +#ifdef __USE_GNU +/* For `recvmmsg' and `sendmmsg'. */ +struct mmsghdr + { + struct msghdr msg_hdr; /* Actual message header. */ + unsigned int msg_len; /* Number of received or sent bytes for the + entry. */ + }; +#endif /* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. @@ -190,6 +199,17 @@ extern ssize_t sendmsg (int __fd, const struct msghdr *__message, int __flags); libc_hidden_proto(sendmsg) +#ifdef __USE_GNU +/* Send a VLEN messages as described by VMESSAGES to socket FD. + Returns the number of datagrams successfully written or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t sendmmsg (int __fd, struct mmsghdr *__vmessages, + size_t __vlen, int __flags); +libc_hidden_proto(sendmmsg) +#endif + /* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors. @@ -198,6 +218,16 @@ libc_hidden_proto(sendmsg) extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); libc_hidden_proto(recvmsg) +#ifdef __USE_GNU +/* Receive up to VLEN messages as described by VMESSAGES from socket FD. + Returns the number of messages received or -1 for errors. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t recvmmsg (int __fd, struct mmsghdr *__vmessages, + size_t vlen, int __flags, struct timespec *__tmo); +libc_hidden_proto(recvmmsg) +#endif /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index 332e70e..bed76c3 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -47,7 +47,8 @@ CSRC-$(UCLIBC_HAS_RESOLVER_SUPPORT) += \ socketcalls_CSRC-y += \ accept.c bind.c connect.c getpeername.c getsockname.c \ getsockopt.c listen.c recv.c recvfrom.c recvmsg.c send.c sendmsg.c \ - sendto.c setsockopt.c shutdown.c socket.c socketpair.c + sendto.c setsockopt.c shutdown.c socket.c socketpair.c \ + recvmmsg.c sendmmsg.c socketcalls_CSRC-$(UCLIBC_LINUX_SPECIFIC) += accept4.c CSRC-$(UCLIBC_HAS_SOCKET) += $(socketcalls_CSRC-y) opensock.c diff --git a/libc/inet/recvmmsg.c b/libc/inet/recvmmsg.c new file mode 100644 index 0000000..003b5a6 --- /dev/null +++ b/libc/inet/recvmmsg.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen andersen@uclibc.org + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_recvmmsg +#include "socketcalls.c" diff --git a/libc/inet/sendmmsg.c b/libc/inet/sendmmsg.c new file mode 100644 index 0000000..f1557fe --- /dev/null +++ b/libc/inet/sendmmsg.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen andersen@uclibc.org + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_sendmmsg +#include "socketcalls.c" diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index 1fef810..cb28140 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -29,6 +29,8 @@ #define SYS_SENDMSG 16 #define SYS_RECVMSG 17 #define SYS_ACCEPT4 18 +#define SYS_RECVMMSG 19 +#define SYS_SENDMMSG 20 #endif /* exposed on x86 since Linux commit 9dea5dc921b5f4045a18c63eb92e84dc274d17eb */ @@ -283,6 +285,30 @@ CANCELLABLE_SYSCALL(ssize_t, recvmsg, (int sockfd, struct msghdr *msg, int flags lt_libc_hidden(recvmsg) #endif +#ifdef L_recvmmsg +static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, + int flags, struct timespec *tmo) +{ +# ifdef __NR_recvmmsg + return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); +# else + unsigned long args[5]; + + args[0] = sockfd; + args[1] = (unsigned long) msg; + args[2] = vlen; + args[3] = flags; + args[4] = (unsigned long) tmo; + return (ssize_t)__socketcall(SYS_RECVMMSG, args); +# endif +} +CANCELLABLE_SYSCALL(ssize_t, recvmmsg, + (int sockfd, struct mmsghdr *msg, size_t vlen, int flags, + struct timespec *tmo), + (sockfd, msg, vlen, flags, tmo)) +lt_libc_hidden(recvmmsg) +#endif + #ifdef L_send static ssize_t __NC(send)(int sockfd, const void *buffer, size_t len, int flags) { @@ -324,6 +350,28 @@ CANCELLABLE_SYSCALL(ssize_t, sendmsg, (int sockfd, const struct msghdr *msg, int lt_libc_hidden(sendmsg) #endif +#ifdef L_sendmmsg +static ssize_t __NC(sendmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, + int flags) +{ +# ifdef __NR_sendmmsg + return (ssize_t)INLINE_SYSCALL(sendmmsg, 4, sockfd, msg, vlen, flags); +# else + unsigned long args[4]; + + args[0] = sockfd; + args[1] = (unsigned long) msg; + args[2] = vlen; + args[3] = flags; + return (ssize_t)__socketcall(SYS_SENDMMSG, args); +# endif +} +CANCELLABLE_SYSCALL(ssize_t, sendmmsg, + (int sockfd, struct mmsghdr *msg, size_t vlen, int flags), + (sockfd, msg, vlen, flags)) +lt_libc_hidden(sendmmsg) +#endif + #ifdef L_sendto ssize_t __NC(sendto)(int sockfd, const void *buffer, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) diff --git a/libpthread/nptl/Makefile.in b/libpthread/nptl/Makefile.in index 068eee4..a2f30ac 100644 --- a/libpthread/nptl/Makefile.in +++ b/libpthread/nptl/Makefile.in @@ -166,11 +166,13 @@ CFLAGS-readv.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recv.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recvfrom.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recvmsg.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-__rt_sigtimedwait.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-__rt_sigwaitinfo.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-send.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sendmsg.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sendto.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sigpause.c = -fexceptions CFLAGS-sigsuspend.c = -fexceptions -fasynchronous-unwind-tables -- 2.7.4
Hi Guo, Guo Ren wrote,
This is the right patch, and forget previous wrong patch.
Okay, thanks. It is always good to use PATCH v2 for a followup patch. I will add your three patches to the queue for the next full regression run, which normally takes some time to run through. Do you have other generic patches to add or is just the big c-sky support patch left out?
best regards Waldemar
Hi, Walemar
Okay, thanks. It is always good to use PATCH v2 for a followup patch.
OK, I'll learn it.
I will add your three patches to the queue for the next full regression run, which normally takes some time to run through. Do you have other generic patches to add or is just the big c-sky support patch left out?
No more generic patch left, and just a big c-sky support patch.
best regards Guo Ren
Hi Guo, Guo Ren wrote,
Hi, Walemar
Okay, thanks. It is always good to use PATCH v2 for a followup patch.
OK, I'll learn it.
I will add your three patches to the queue for the next full regression run, which normally takes some time to run through. Do you have other generic patches to add or is just the big c-sky support patch left out?
No more generic patch left, and just a big c-sky support patch.
All three generic patches pushed,
best regards Waldemar