A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

Add a small 32-byte write buffer to fdprintf.

Avoids a call to write() for every output character. It doesn't
need to be very large to have a great effect on speed and realize
most of the potential.

Change-Id: I11820c1968ed7b20aa00e106a022c1b864b03d21

+23 -4
+23 -4
firmware/common/fdprintf.c
··· 19 19 * 20 20 ****************************************************************************/ 21 21 #include <limits.h> 22 + #include "system.h" 22 23 #include "file.h" 23 24 #include "vuprintf.h" 24 25 26 + #define FPR_WRBUF_CKSZ 32 /* write buffer chunk size */ 27 + 25 28 struct for_fprintf { 26 29 int fd; /* where to store it */ 27 30 int rem; /* amount remaining */ 31 + int idx; /* index of next buffer write */ 32 + unsigned char wrbuf[FPR_WRBUF_CKSZ]; /* write buffer */ 28 33 }; 29 34 35 + static int fpr_buffer_flush(struct for_fprintf *fpr) 36 + { 37 + /* set idx to actual but negative unflushed count to signal error */ 38 + ssize_t done = write(fpr->fd, fpr->wrbuf, fpr->idx); 39 + fpr->idx = MAX(done, 0) - fpr->idx; 40 + return fpr->idx; 41 + } 42 + 30 43 static int fprfunc(void *pr, int letter) 31 44 { 32 45 struct for_fprintf *fpr = (struct for_fprintf *)pr; 33 46 34 - /* TODO: add a small buffer to reduce write() calls */ 35 - if (write(fpr->fd, &(char){ letter }, 1) > 0) { 36 - return --fpr->rem; 47 + if (fpr->idx >= FPR_WRBUF_CKSZ && fpr_buffer_flush(fpr)) { 48 + return -1; /* don't count this one */ 37 49 } 38 50 39 - return -1; 51 + fpr->wrbuf[fpr->idx++] = letter; 52 + return --fpr->rem; 40 53 } 41 54 42 55 int fdprintf(int fd, const char *fmt, ...) ··· 47 60 48 61 fpr.fd = fd; 49 62 fpr.rem = INT_MAX; 63 + fpr.idx = 0; 50 64 51 65 va_start(ap, fmt); 52 66 bytes = vuprintf(fprfunc, &fpr, fmt, ap); 53 67 va_end(ap); 68 + 69 + /* flush any tail bytes */ 70 + if (fpr.idx < 0 || fpr_buffer_flush(&fpr)) { 71 + bytes += fpr.idx; /* adjust for unflushed bytes */ 72 + } 54 73 55 74 return bytes; 56 75 }