[uclibc-ng-devel] recvmmsg/sendmmsg: add recvmmsg sendmmsg support.

Message ID 1506432735-21968-1-git-send-email-ren_guo@c-sky.com
State New
Headers show
Series
  • [uclibc-ng-devel] recvmmsg/sendmmsg: add recvmmsg sendmmsg support.
Related show

Commit Message

Guo Ren Sept. 26, 2017, 1:32 p.m.
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

Patch

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..83bad12 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(recvmmsg, 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