[netperf-dev] netperf2 commit notice r587 - trunk/src
raj at netperf.org
raj at netperf.org
Wed May 30 17:54:20 PDT 2012
Author: raj
Date: 2012-05-30 17:54:20 -0700 (Wed, 30 May 2012)
New Revision: 587
Modified:
trunk/src/nettest_bsd.c
trunk/src/nettest_omni.c
Log:
experiment a bit with splice() for a zero-copy receive
Modified: trunk/src/nettest_bsd.c
===================================================================
--- trunk/src/nettest_bsd.c 2012-05-30 22:53:02 UTC (rev 586)
+++ trunk/src/nettest_bsd.c 2012-05-31 00:54:20 UTC (rev 587)
@@ -1243,6 +1243,8 @@
/* local system. of course, this may not be possible... */
#ifdef SO_RCV_COPYAVOID
+ /* this is ancient vestigial HP-UX code that should probably go away
+ one day */
if (loc_rcvavoid) {
if (setsockopt(temp_socket,
SOL_SOCKET,
@@ -1255,10 +1257,7 @@
loc_rcvavoid = 0;
}
}
-#else
- /* it wasn't compiled in... */
- loc_rcvavoid = 0;
-#endif /* SO_RCV_COPYAVOID */
+#endif
#ifdef SO_SND_COPYAVOID
if (loc_sndavoid) {
@@ -1273,9 +1272,6 @@
loc_sndavoid = 0;
}
}
-#else
- /* it was not compiled in... */
- loc_sndavoid = 0;
#endif
/* Now, we will see about setting the TCP_NODELAY flag on the local */
Modified: trunk/src/nettest_omni.c
===================================================================
--- trunk/src/nettest_omni.c 2012-05-30 22:53:02 UTC (rev 586)
+++ trunk/src/nettest_omni.c 2012-05-31 00:54:20 UTC (rev 587)
@@ -2884,6 +2884,116 @@
return len;
}
+#if defined(__linux)
+static int
+recv_data_no_copy(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) {
+
+
+ static int pfd[2] = {-1, -1};
+ static int fdnull = -1;
+
+
+ char *temp_message_ptr;
+ int bytes_left;
+ int bytes_recvd;
+ int my_recvs;
+ int my_flags = 0; /* will we one day want to set MSG_WAITALL? */
+ int ret;
+
+ if (pfd[0] == -1) {
+ if (pipe(pfd)) {
+ fprintf(where,
+ "%s pipe call failed with errno %d '%s'\n",
+ __FUNCTION__,
+ errno,
+ strerror(errno));
+ return -4; /* this will cause recv_data to do things the
+ old-fashioned way for the test */
+ }
+ if ((fdnull = open("/dev/null",O_WRONLY)) == -1) {
+ fprintf(where,
+ "%s open call failed with errno %d '%s'\n",
+ __FUNCTION__,
+ errno,
+ strerror(errno));
+ return -4;
+ }
+ }
+
+ /* receive data off the data_socket, ass-u-me-ing a blocking socket
+ all the way!-) 2008-01-08 */
+ my_recvs = 0;
+ bytes_left = bytes_to_recv;
+
+ if (debug > 1) {
+ fprintf(where,
+ "%s sock %d, ring elt %p, bytes %d, source %p, srclen %d, flags %x, num_recv %p\n",
+ __FUNCTION__,
+ data_socket,
+ recv_ring,
+ bytes_to_recv,
+ source,
+ (source != NULL) ? *sourcelen : -1,
+ flags,
+ num_receives);
+ fflush(where);
+ }
+ do {
+
+ bytes_recvd = splice(data_socket,
+ NULL,
+ pfd[1],
+ NULL,
+ bytes_left,
+ my_flags);
+
+
+ if (bytes_recvd > 0) {
+ if (splice(pfd[0],
+ NULL,
+ fdnull,
+ NULL,
+ bytes_recvd,
+ my_flags) != bytes_recvd) {
+ return -3;
+ }
+ bytes_left -= bytes_recvd;
+ }
+ else {
+ break;
+ }
+ my_recvs++; /* should the pair of splices count as one? */
+ } while ((bytes_left > 0) && (flags & NETPERF_WAITALL));
+
+ *num_receives = my_recvs;
+
+ /* OK, we are out of the loop - now what? */
+ if (bytes_recvd < 0) {
+ /* did the timer hit, or was there an error? */
+ if (SOCKET_EINTR(bytes_recvd))
+ {
+ /* We hit the end of a timed test. */
+ return -1;
+ }
+ /* it was a hard error */
+ return -3;
+ }
+
+
+ /* this looks a little funny, but should be correct. if we had
+ NETPERF_WAITALL set and we got here, it means we got all the
+ bytes of the request/response. otherwise we would have hit the
+ error or end of test cases. if NETPERF_WAITALL isn't set, this
+ is a STREAM test, and we will have only made one call to recv, so
+ bytes_recvd will be accurate. */
+ if (bytes_left)
+ return bytes_recvd;
+ else
+ return bytes_to_recv;
+
+}
+#endif
+
int
recv_data(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) {
@@ -2893,6 +3003,17 @@
int my_recvs;
int my_flags = 0; /* will we one day want to set MSG_WAITALL? */
+#if defined(__linux)
+ int ret;
+ if (loc_rcvavoid == 1) {
+ ret = recv_data_no_copy(data_socket, recv_ring, bytes_to_recv, source, sourcelen, flags, num_receives);
+ if (ret != -4)
+ return ret;
+ else
+ loc_rcvavoid = 0;
+ }
+#endif
+
/* receive data off the data_socket, ass-u-me-ing a blocking socket
all the way!-) 2008-01-08 */
my_recvs = 0;
@@ -7111,18 +7232,8 @@
/* it for everything, everywhere, if we really */
/* can. of course, we don't know anything */
/* about the remote... */
-#ifdef SO_SND_COPYAVOID
loc_sndavoid = 1;
-#else
- loc_sndavoid = 0;
- printf("Local send copy avoidance not available.\n");
-#endif
-#ifdef SO_RCV_COPYAVOID
loc_rcvavoid = 1;
-#else
- loc_rcvavoid = 0;
- printf("Local recv copy avoidance not available.\n");
-#endif
rem_sndavoid = 1;
rem_rcvavoid = 1;
break;
More information about the netperf-dev
mailing list