Changeset 22cdd39


Ignore:
Timestamp:
03/30/10 14:30:48 (11 years ago)
Author:
Perry Lorier <perry@…>
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:
7283767
Parents:
212f9da2
Message:

Correctly accumulate data into large buffers for write

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/iow-stdio.c

    r026eb88 r22cdd39  
    118118static off_t stdio_wwrite(iow_t *iow, const char *buffer, off_t len)
    119119{
    120         struct iovec iov[2];
    121         int err;
     120        int towrite = len;
    122121        /* Round down size to the nearest multiple of MIN_WRITE_SIZE */
    123122
    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);
     123        assert(towrite >= 0);
     124
     125        while (DATA(iow)->offset + towrite >= MIN_WRITE_SIZE) {
     126                int err;
     127                struct iovec iov[2];
     128                int total = towrite - (DATA(iow)->offset+towrite) % MIN_WRITE_SIZE;
     129                int amount = total;
     130                int count=0;
     131                if (DATA(iow)->offset) {
     132                        iov[count].iov_base = DATA(iow)->buffer;
     133                        iov[count].iov_len = min(DATA(iow)->offset,amount);
     134                        amount -= iov[count].iov_len;
     135                        ++count;
     136                }
     137                if (towrite) {
     138                        iov[count].iov_base = (void*)buffer;    /* cast away constness, which is safe
     139                                                                 * here
     140                                                                 */
     141                        iov[count].iov_len = amount;
     142                        amount -= iov[count].iov_len;
     143                        ++count;
     144                }
     145                assert(amount == 0);
     146                err=writev(DATA(iow)->fd, iov, count);
    133147                if (err==-1)
    134148                        return -1;
     149                if (err != total)
     150                        fprintf(stderr,"Wrote %d/%d\n",err,total);
     151
    135152                /* Drop off "err" bytes from the beginning of the buffers */
    136                 amount = min(DATA(iow)->offset, err);
     153                amount = min(DATA(iow)->offset, err); /* How much we took out of the buffer */
     154                memmove(DATA(iow)->buffer,
     155                        DATA(iow)->buffer+amount,
     156                        DATA(iow)->offset-amount);
    137157                DATA(iow)->offset -= amount;
    138                 err -= amount;
     158
     159                err -= amount; /* How much was written */
     160
     161                assert(err <= towrite);
     162
    139163                buffer += err;
    140                 len -= err;
     164                towrite -= err;
     165
     166                assert(DATA(iow)->offset == 0);
    141167        }
    142168
     
    144170         * that this is true
    145171         */
    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;
     172        assert(DATA(iow)->offset + towrite <= MIN_WRITE_SIZE);
     173        assert(towrite >= 0);
     174
     175        if (towrite > 0) {
     176                /* Copy the remainder into the buffer to write next time. */
     177                memcpy(DATA(iow)->buffer + DATA(iow)->offset, buffer, towrite);
     178                DATA(iow)->offset += towrite;
     179        }
    152180
    153181        return len;
     
    165193                fcntl(DATA(iow)->fd,F_SETFL, err & ~O_DIRECT);
    166194        }
    167         write(DATA(iow)->fd, DATA(iow)->buffer, DATA(iow)->offset);
     195#endif
     196        err=write(DATA(iow)->fd, DATA(iow)->buffer, DATA(iow)->offset);
    168197        DATA(iow)->offset = 0;
    169 #endif
    170198        close(DATA(iow)->fd);
    171199        free(iow->data);
Note: See TracChangeset for help on using the changeset viewer.