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_...@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 <ander...@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 <ander...@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

_______________________________________________
devel mailing list
devel@uclibc-ng.org
https://mailman.uclibc-ng.org/cgi-bin/mailman/listinfo/devel

Reply via email to