writev/readv addition to file_operation proposal

From: Abramo Bagnara (abramo@alsa-project.org)
Date: Tue Feb 08 2000 - 13:39:38 EST


Without any official answer, with no objections and the enthusiastic
welcome of LWN, I'm a bit embarassed about what to do now.

I'm unable to understand if a missing answer need to be interpreted as a
silent refusal, as an invitation to write down the patch or as a kick in
the ass ;-)

Or perhaps only an invitation to wait some time...

Are there some silently refused proposal veteran that offer me a
shoulder to cry over or some consolation words? ;-)

Linus, don't show me a rock heart... how is it possible to not answer to
a crying man?

-- 
Abramo Bagnara                       mailto:abramo@alsa-project.org

Opera Unica Via Emilia Interna, 140 Phone: +39.0546.656023 48014 Castel Bolognese (RA) - Italy Fax: +39.0546.656023

ALSA project is http://www.alsa-project.org sponsored by SuSE Linux http://www.suse.com

It sounds good!

#include <errno.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/uio.h>

#define BUFSIZE 1024

/* Require: new writev semantics: each iov_base represent a different voice In this implementation write size is reduced by buffer boundary, but this can be avoided using voices*2 iovec elements

Without to need a kernel change we may use a special ioctl to do the writev stuff, but the writev solution is *far more* beautiful. */

int stream_with_new_writev(void) { int voices = 2; int pfd = 3; struct voice_buf { char *buf; int woff; int used; int free; } bufs[voices]; struct iovec iovec[voices]; int fd[voices]; int v, result; fd_set rfds, wfds; int writable; int fds = pfd; int roff = 0; for (v = 0; v < voices; ++v) { bufs[v].buf = malloc(BUFSIZE); bufs[v].woff = 0; bufs[v].used = 0; bufs[v].free = BUFSIZE; if (fd[v] > fds) fds = fd[v]; } fds++; writable = 0; while (1) { FD_ZERO(&rfds); for (v = 0; v < voices; ++v) { if (bufs[v].free > 0) FD_SET(fd[v], &rfds); } FD_ZERO(&wfds); if (writable > 0) FD_SET(pfd, &wfds); result = select(fds, &rfds, &wfds, NULL, NULL); if (FD_ISSET(pfd, &wfds)) { for (v = 0; v < voices; ++v) { iovec[v].iov_base = bufs[v].buf+roff; iovec[v].iov_len = writable; } result = writev(pfd, iovec, voices); if (result > 0) { int empty = 1; if (result % voices != 0) { printf("driver failure\n"); return -1; } result /= voices; roff += result; if (roff == BUFSIZE) roff = 0; for (v = 0; v < voices; ++v) { bufs[v].used -= result; bufs[v].free += result; if (bufs[v].used > 0) empty = 0; } if (empty && roff > 0) { for (v = 0; v < voices; ++v) bufs[v].woff = 0; roff = 0; } } else { printf("writev error\n"); return -1; } } writable = BUFSIZE - roff; for (v = 0; v < voices; ++v) { if (FD_ISSET(fd[v], &rfds)) { int readable = BUFSIZE - bufs[v].woff; if (readable > bufs[v].free) readable = bufs[v].free; result = read(fd[v], bufs[v].buf + bufs[v].woff, readable); if (result < 0) { printf("read error\n"); return -1; } bufs[v].woff += result; bufs[v].used += result; bufs[v].free -= result; if (bufs[v].woff == BUFSIZE) bufs[v].woff = 0; } if (bufs[v].used < writable) writable = bufs[v].used; } } return 0; }

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 15 2000 - 21:00:13 EST