©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c2/writev.c

Go to the documentation of this file.
00001 /*
00002     writev test program
00003     AUP2, Sec. 2.15 (not in book)
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 #include "defs.h"
00022 #include <sys/uio.h>
00023 
00024 #define REPS 50000
00025 #define PIECES 16
00026 #define PIECE_SIZE 200
00027 
00028 int main(void)
00029 {
00030     int i, fd, count, /*fillerlen,*/ bufsize, iovcnt;
00031     ssize_t n;
00032     char *piece[PIECES];
00033 #if 0
00034     struct data1 {
00035         int num;
00036         char s[20];
00037     } d1, d3;
00038     struct data2 {
00039         int num;
00040         char s[50];
00041     } d2;
00042     char *buf, *filler;
00043 #endif
00044     struct iovec v[PIECES];
00045 
00046 #ifdef BSD_DERIVED
00047 #define IOV_MAX 1024 /* sys/uio.h defines UIO_MAXIOV, but only if _KERNEL is defined */
00048 #endif
00049     iovcnt = PIECES;
00050     if (iovcnt > IOV_MAX)
00051         iovcnt = IOV_MAX;
00052     for (i = 0; i < iovcnt; i++) {
00053         ec_null( piece[i] = malloc(PIECE_SIZE) )
00054         memset(piece[i], 123, PIECE_SIZE);
00055         v[i].iov_base = piece[i];
00056         v[i].iov_len = PIECE_SIZE;
00057     }
00058     printf("iovcnt = %d; piece size = %d; reps = %d\n",
00059       iovcnt, PIECE_SIZE, REPS);
00060 
00061     printf("IOV_MAX = %ld; SSIZE_MAX = %ld\n",
00062       (long)IOV_MAX, (long)SSIZE_MAX);
00063 
00064     printf("sizeof(int) = %d;BUFSIZ = %d\n",
00065       sizeof(int), BUFSIZ);
00066 
00067     ec_neg1( fd = open("a.tmp", O_RDWR | O_CREAT | O_TRUNC, PERM_FILE) )
00068 /*
00069     We would like a universal way to determine the best buffer size. _PC_ALLOC_SIZE_MIN
00070     (assuming that's even the right symbol) is optional, so not universal.
00071 */
00072     bufsize = 1024;
00073 /*
00074 #ifdef FREEBSD
00075     bufsize = 4096;
00076 #else
00077     bufsize = fpathconf(fd, _PC_ALLOC_SIZE_MIN);
00078     printf("_PC_ALLOC_SIZE_MIN = %d\n", bufsize);
00079 #endif
00080 */
00081 
00082 #if 0
00083     ec_null( filler = malloc(bufsize) )
00084     ec_null( buf = malloc(bufsize) )
00085 
00086     d1.num = 123;
00087     strcpy(d1.s, "hello");
00088     d2.num = 456;
00089     strcpy(d2.s, "goodbye");
00090     d3.num = 789;
00091     strcpy(d3.s, "thankyou");
00092     memset(filler, 0, bufsize);
00093     fillerlen = bufsize - sizeof(d1) - sizeof(d2) - sizeof(d3);
00094 
00095     v[0].iov_base = &d1;
00096     v[0].iov_len = sizeof(d1);
00097     v[1].iov_base = &d2;
00098     v[1].iov_len = sizeof(d2);
00099     v[2].iov_base = &d3;
00100     v[2].iov_len = sizeof(d3);
00101     v[3].iov_base = filler;
00102     v[3].iov_len = fillerlen;
00103     ec_neg1( n = writev(fd, v, sizeof(v) / sizeof(v[0])) )
00104     printf("%ld bytes written\n", (long)n);
00105 
00106     memset(&d1, 0, sizeof(d1));
00107     memset(&d2, 0, sizeof(d2));
00108     memset(&d3, 0, sizeof(d3));
00109 
00110     if (lseek(fd, 0, SEEK_SET) == -1)
00111         syserr("lseek");
00112 
00113     ec_neg1( n = readv(fd, v, sizeof(v) / sizeof(v[0])) )
00114     printf("%ld bytes read\n", (long)n);
00115 
00116     printf("d1: %d %s\n", d1.num, d1.s);
00117     printf("d2: %d %s\n", d2.num, d2.s);
00118     printf("d3: %d %s\n", d3.num, d3.s);
00119 #endif
00120     /* Now do some timing tests. */
00121 
00122     ec_neg1( lseek(fd, 0, SEEK_SET) )
00123     timestart();
00124     for (count = 0; count < REPS; count++)
00125         ec_neg1( n = writev(fd, v, iovcnt) )
00126     timestop("writev");
00127     printf("Position at end = %ld\n", (long)lseek(fd, 0, SEEK_CUR));
00128 
00129     ec_neg1( lseek(fd, 0, SEEK_SET) )
00130     timestart();
00131     for (count = 0; count < REPS; count++)
00132         for (i = 0; i < iovcnt; i++)
00133             ec_neg1( n = write(fd, v[i].iov_base, PIECE_SIZE) )
00134     timestop("write");
00135     printf("Position at end = %ld\n", (long)lseek(fd, 0, SEEK_CUR));
00136 #if 0
00137     ec_neg1( lseek(fd, 0, SEEK_SET) )
00138     timestart();
00139     for (count = 0; count < REPS; count++) {
00140         int offset = 0;
00141         memcpy(buf, &d1, sizeof(d1));
00142         offset += sizeof(d1);
00143         memcpy(buf + offset, &d2, sizeof(d2));
00144         offset += sizeof(d2);
00145         memcpy(buf + offset, &d3, sizeof(d3));
00146         offset += sizeof(d3);
00147         assert(fillerlen == bufsize - offset);
00148         memcpy(buf + offset, filler, fillerlen);
00149         offset += fillerlen;
00150         assert(offset == bufsize);
00151         ec_neg1( n = write(fd, buf, bufsize) )
00152     }
00153     timestop("write (full buffer)");
00154     printf("Position at end = %ld\n", lseek(fd, 0, SEEK_CUR));
00155 #endif
00156     ec_neg1( close(fd) )
00157     exit(EXIT_SUCCESS);
00158 
00159 EC_CLEANUP_BGN
00160     exit(EXIT_FAILURE);
00161 EC_CLEANUP_END
00162 }

Generated on Fri Apr 23 10:56:54 2004 for AUP2 Example Source by doxygen 1.3.1