svlogd: remove unused buffering, stop doing tons of memcpy
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 67ffc44..a588ffe 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -35,7 +35,7 @@
static unsigned verbose;
static int linemax = 1000;
-static int buflen = 1024;
+////static int buflen = 1024;
static int linelen;
static char **fndir;
@@ -49,13 +49,13 @@
static unsigned reopenasap;
static unsigned linecomplete = 1;
static unsigned tmaxflag;
-static iopause_fd in;
+static iopause_fd input;
static const char *replace = "";
static char repl;
static struct logdir {
- char *btmp;
+ ////char *btmp;
/* pattern list to match, in "aa\0bb\0\cc\0\0" form */
char *inst;
char *processor;
@@ -373,7 +373,8 @@
}
}
}
- if (errno) pause2cannot("write to current", ld->name);
+ if (errno)
+ pause2cannot("write to current", ld->name);
}
ld->size += i;
@@ -621,7 +622,7 @@
sig_unblock(SIGCHLD);
sig_unblock(SIGALRM);
sig_unblock(SIGHUP);
- iopause(&in, 1, &trotate, &now);
+ iopause(&input, 1, &trotate, &now);
sig_block(SIGTERM);
sig_block(SIGCHLD);
sig_block(SIGALRM);
@@ -732,6 +733,8 @@
unsigned opt;
unsigned timestamp = 0;
+#define line bb_common_bufsiz1
+
opt_complementary = "tt:vv";
opt = getopt32(argc, argv, "r:R:l:b:tv",
&r, &replace, &l, &b, ×tamp, &verbose);
@@ -741,38 +744,40 @@
}
if (opt & 2) if (!repl) repl = '_'; // -R
if (opt & 4) { // -l
- linemax = xatou_range(l, 0, 1000);
- if (linemax == 0) linemax = 1000;
+ linemax = xatou_range(l, 0, BUFSIZ-26);
+ if (linemax == 0) linemax = BUFSIZ-26;
if (linemax < 256) linemax = 256;
}
if (opt & 8) { // -b
- buflen = xatoi_u(b);
- if (buflen == 0) buflen = 1024;
+ ////buflen = xatoi_u(b);
+ ////if (buflen == 0) buflen = 1024;
}
//if (opt & 0x10) timestamp++; // -t
//if (opt & 0x20) verbose++; // -v
- if (timestamp > 2) timestamp = 2;
+ //if (timestamp > 2) timestamp = 2;
argv += optind;
argc -= optind;
dirn = argc;
if (dirn <= 0) usage();
- if (buflen <= linemax) usage();
+ ////if (buflen <= linemax) usage();
fdwdir = xopen(".", O_RDONLY|O_NDELAY);
coe(fdwdir);
dir = xmalloc(dirn * sizeof(struct logdir));
for (i = 0; i < dirn; ++i) {
dir[i].fddir = -1;
dir[i].fdcur = -1;
- dir[i].btmp = xmalloc(buflen);
+ ////dir[i].btmp = xmalloc(buflen);
dir[i].ppid = 0;
}
- line = xmalloc(linemax + (timestamp ? 26 : 0));
+ /* line = xmalloc(linemax + (timestamp ? 26 : 0)); */
fndir = argv;
- in.fd = 0;
- in.events = IOPAUSE_READ;
- ndelay_on(in.fd);
-
+ input.fd = 0;
+ input.events = IOPAUSE_READ;
+ /* I be damned. Linux 2.6.18: this somehow affects
+ * OTHER processes! Konsole starts to redraw itself much slower!
+ * This persists even after svlogd exits */
+ ndelay_on(input.fd);
sig_block(SIGTERM);
sig_block(SIGCHLD);
sig_block(SIGALRM);
@@ -786,14 +791,16 @@
/* Each iteration processes one line */
while (1) {
- int printlen;
- char *lineptr = line;
+ char stamp[FMT_PTIME];
+ char *lineptr;
+ char *printptr;
char *np;
+ int printlen;
char ch;
+ lineptr = line;
/* Prepare timestamp if needed */
if (timestamp) {
- char stamp[FMT_PTIME];
taia_now(&now);
switch (timestamp) {
case 1:
@@ -803,8 +810,6 @@
fmt_ptime30nul(stamp, &now);
break;
}
- memcpy(line, stamp, 25);
- line[25] = ' ';
lineptr += 26;
}
@@ -819,8 +824,8 @@
if (sz <= 0) /* EOF or error on stdin */
exitasap = 1;
else {
+ np = memchr(lineptr + stdin_cnt, '\n', sz);
stdin_cnt += sz;
- np = memchr(lineptr, '\n', stdin_cnt);
}
}
if (stdin_cnt <= 0 && exitasap)
@@ -828,21 +833,33 @@
/* Search for '\n' (in fact, np already holds the result) */
linelen = stdin_cnt;
- if (np) linelen = np - lineptr + 1;
+ if (np) {
+ print_to_nl: /* NB: starting from here lineptr may point
+ * farther out into line[] */
+ linelen = np - lineptr + 1;
+ }
/* linelen == no of chars incl. '\n' (or == stdin_cnt) */
ch = lineptr[linelen-1];
- printlen = linelen + (timestamp ? 26 : 0);
- /* write out line[0..printlen-1] to each log destination */
+ /* write out lineptr[0..linelen-1] to each log destination */
+ /* (or lineptr[-26..linelen-1] if timestamping) */
+ printlen = linelen;
+ printptr = lineptr;
+ if (timestamp) {
+ printlen += 26;
+ printptr -= 26;
+ memcpy(printptr, stamp, 25);
+ printptr[25] = ' ';
+ }
for (i = 0; i < dirn; ++i) {
struct logdir *ld = &dir[i];
if (ld->fddir == -1) continue;
if (ld->inst)
logmatch(ld);
if (ld->matcherr == 'e')
- full_write(2, line, printlen);
+ full_write(2, printptr, printlen);
if (ld->match != '+') continue;
- buffer_pwrite(i, line, printlen);
+ buffer_pwrite(i, printptr, printlen);
}
/* If we didn't see '\n' (long input line), */
@@ -851,9 +868,9 @@
/* lineptr is emptied now, safe to use as buffer */
stdin_cnt = exitasap ? -1 : buffer_pread(0, lineptr, linemax);
if (stdin_cnt <= 0) { /* EOF or error on stdin */
+ exitasap = 1;
lineptr[0] = ch = '\n';
linelen = 1;
- exitasap = 1;
stdin_cnt = 1;
} else {
linelen = stdin_cnt;
@@ -871,10 +888,17 @@
}
}
- /* Move unprocessed data to the front of line */
stdin_cnt -= linelen;
- if (stdin_cnt > 0) /* TODO: slow if buffer is big */
- memmove(lineptr, &lineptr[linelen], stdin_cnt);
+ if (stdin_cnt > 0) {
+ lineptr += linelen;
+ /* If we see another '\n', we don't need to read
+ * next piece of input: can print what we have */
+ np = memchr(lineptr, '\n', stdin_cnt);
+ if (np)
+ goto print_to_nl;
+ /* Move unprocessed data to the front of line */
+ memmove((timestamp ? line+26 : line), lineptr, stdin_cnt);
+ }
}
for (i = 0; i < dirn; ++i) {