Changeset 026eb88
- Timestamp:
- 03/19/10 14:33:17 (11 years ago)
- Branches:
- 4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
- Children:
- 2b4316b
- Parents:
- d99c759
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/iow-stdio.c
r29d4438 r026eb88 37 37 #include <sys/types.h> 38 38 #include <sys/stat.h> 39 #include <sys/uio.h> 39 40 #include <fcntl.h> 40 41 #include <stdlib.h> 41 42 #include <unistd.h> 42 43 #include <string.h> 44 #include <assert.h> 43 45 44 46 /* Libtrace IO module implementing a standard IO writer, i.e. no decompression 45 47 */ 46 48 49 enum { MIN_WRITE_SIZE = 4096 }; 50 47 51 struct stdiow_t { 52 char buffer[MIN_WRITE_SIZE]; 53 int offset; 48 54 int fd; 49 55 }; … … 52 58 53 59 #define DATA(iow) ((struct stdiow_t *)((iow)->data)) 60 61 static int safe_open(const char *filename) 62 { 63 int fd; 64 /* Try opening with O_DIRECT */ 65 #ifdef O_DIRECT 66 fd = open(filename, 67 O_WRONLY 68 |O_CREAT 69 |O_TRUNC 70 |(force_directio_write?O_DIRECT:0), 71 0666); 72 if (fd != -1) 73 return fd; 74 #endif 75 /* If that failed (or we don't support O_DIRECT) try opening without */ 76 fd = open(filename, 77 O_WRONLY 78 |O_CREAT 79 |O_TRUNC, 80 0666); 81 if (fd != -1) 82 return fd; 83 return fd; 84 } 54 85 55 86 iow_t *stdio_wopen(const char *filename) … … 61 92 if (strcmp(filename,"-") == 0) 62 93 DATA(iow)->fd = 1; /* STDOUT */ 63 else 64 DATA(iow)->fd = open(filename, 65 O_WRONLY 66 |O_CREAT 67 |O_TRUNC 68 |(force_directio_write?O_DIRECT:0), 69 0666); 94 else { 95 DATA(iow)->fd = safe_open(filename); 96 } 70 97 71 98 if (DATA(iow)->fd == -1) { … … 74 101 } 75 102 103 DATA(iow)->offset = 0; 104 76 105 return iow; 77 106 } 78 107 108 #define min(a,b) ((a)<(b) ? (a) : (b)) 109 #define max(a,b) ((a)>(b) ? (a) : (b)) 110 /* Round A Down to the nearest multiple of B */ 111 #define rounddown(a,b) ((a)-((a)%b) 112 113 /* When doing directio (O_DIRECT) we need to make sure that we write multiples of MIN_WRITE_SIZE. 114 * So we accumulate data into DATA(iow)->buffer, and write it out when we get at least MIN_WRITE_SIZE. 115 * 116 * Since most writes are likely to be larger than MIN_WRITE_SIZE optimise for that case. 117 */ 79 118 static off_t stdio_wwrite(iow_t *iow, const char *buffer, off_t len) 80 119 { 81 return write(DATA(iow)->fd,buffer,len); 120 struct iovec iov[2]; 121 int err; 122 /* Round down size to the nearest multiple of MIN_WRITE_SIZE */ 123 124 assert(len >= 0); 125 126 if (DATA(iow)->offset + len >= MIN_WRITE_SIZE) { 127 int amount; 128 iov[0].iov_base = DATA(iow)->buffer; 129 iov[0].iov_len = DATA(iow)->offset; 130 iov[1].iov_base = (void*)buffer; /* cast away constness, which is safe here */ 131 iov[1].iov_len = len - (DATA(iow)->offset+len) % MIN_WRITE_SIZE; 132 err=writev(DATA(iow)->fd, iov, 2); 133 if (err==-1) 134 return -1; 135 /* Drop off "err" bytes from the beginning of the buffers */ 136 amount = min(DATA(iow)->offset, err); 137 DATA(iow)->offset -= amount; 138 err -= amount; 139 buffer += err; 140 len -= err; 141 } 142 143 /* Make sure we're not going to overflow the buffer. The above writev should assure 144 * that this is true 145 */ 146 assert(DATA(iow)->offset + len <= MIN_WRITE_SIZE); 147 assert(len >= 0); 148 149 /* Copy the remainder into the buffer to write next time. */ 150 memcpy(DATA(iow)->buffer + DATA(iow)->offset, buffer, len); 151 DATA(iow)->offset += len; 152 153 return len; 82 154 } 83 155 84 156 static void stdio_wclose(iow_t *iow) 85 157 { 158 long err; 159 /* Now, there might be some non multiple of the direct filesize left over, if so turn off 160 * O_DIRECT and write the final chunk. 161 */ 162 #ifdef O_DIRECT 163 err=fcntl(DATA(iow)->fd, F_GETFL); 164 if (err != -1 && (err & O_DIRECT) != 0) { 165 fcntl(DATA(iow)->fd,F_SETFL, err & ~O_DIRECT); 166 } 167 write(DATA(iow)->fd, DATA(iow)->buffer, DATA(iow)->offset); 168 DATA(iow)->offset = 0; 169 #endif 86 170 close(DATA(iow)->fd); 87 171 free(iow->data);
Note: See TracChangeset
for help on using the changeset viewer.