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