From 45d9b20b9e8bf96f84e7978b4548746ee788f6b8 Mon Sep 17 00:00:00 2001 From: Lorenzo Cogotti Date: Mon, 18 Oct 2021 12:04:07 +0200 Subject: [PATCH] [lonetix/bufio] Optimize buffer write operations avoiding copies, also introduce smallbytecopy.h --- lonetix/bufio.c | 46 +++++++++++++++++++++++++++++--------- lonetix/include/df/bufio.h | 10 +++++---- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/lonetix/bufio.c b/lonetix/bufio.c index d2df88a..dd4cea2 100644 --- a/lonetix/bufio.c +++ b/lonetix/bufio.c @@ -12,6 +12,7 @@ #include "sys/sys_local.h" // for Sys_SetErrStat() - vsnprintf() #include "bufio.h" #include "numlib.h" +#include "smallbytecopy.h" #include #include @@ -73,7 +74,7 @@ void Bufio_Close(Stmrdbuf *sb) if (sb->ops->Close) sb->ops->Close(sb->streamp); } -Sint64 Bufio_Flush(Stmwrbuf *sb) +NOINLINE Sint64 Bufio_Flush(Stmwrbuf *sb) { assert(sb->ops->Write); @@ -90,6 +91,16 @@ Sint64 Bufio_Flush(Stmwrbuf *sb) return sb->totalOut; } +Sint64 _Bufio_SmallPutsn(Stmwrbuf *sb, const char *s, size_t nbytes) +{ + if (sb->availOut + nbytes > sizeof(sb->buf) && Bufio_Flush(sb) == -1) + return -1; + + _smallbytecopy64(sb->buf + sb->availOut, s, nbytes); + sb->availOut += nbytes; + return nbytes; +} + Sint64 _Bufio_Putsn(Stmwrbuf *sb, const char *s, size_t nbytes) { if (sb->availOut + nbytes > sizeof(sb->buf) && Bufio_Flush(sb) == -1) @@ -104,26 +115,41 @@ Sint64 _Bufio_Putsn(Stmwrbuf *sb, const char *s, size_t nbytes) Sint64 Bufio_Putu(Stmwrbuf *sb, unsigned long long val) { - char buf[DIGS(val) + 1]; + if (sb->availOut + DIGS(val) + 1 > sizeof(sb->buf) && Bufio_Flush(sb) == -1) + return -1; - char *eptr = Utoa(val, buf); - return Bufio_Putsn(sb, buf, eptr - buf); + char *sptr = sb->buf + sb->availOut; + char *eptr = Utoa(val, sptr); + Sint64 n = eptr - sptr; + + sb->availOut += n; + return n; } Sint64 Bufio_Putx(Stmwrbuf *sb, unsigned long long val) { - char buf[XDIGS(val) + 1]; + if (sb->availOut + XDIGS(val) + 1 > sizeof(sb->buf) && Bufio_Flush(sb) == -1) + return -1; - char *eptr = Xtoa(val, buf); - return Bufio_Putsn(sb, buf, eptr - buf); + char *sptr = sb->buf + sb->availOut; + char *eptr = Xtoa(val, sptr); + Sint64 n = eptr - sptr; + + sb->availOut += n; + return n; } Sint64 Bufio_Puti(Stmwrbuf *sb, long long val) { - char buf[1 + DIGS(val) + 1]; + if (sb->availOut + 1 + DIGS(val) + 1 > sizeof(sb->buf) && Bufio_Flush(sb) == -1) + return -1; - char *eptr = Itoa(val, buf); - return Bufio_Putsn(sb, buf, eptr - buf); + char *sptr = sb->buf + sb->availOut; + char *eptr = Itoa(val, sptr); + Sint64 n = eptr - sptr; + + sb->availOut += n; + return n; } Sint64 Bufio_Putf(Stmwrbuf *sb, double val) diff --git a/lonetix/include/df/bufio.h b/lonetix/include/df/bufio.h index ad36396..e5fc386 100644 --- a/lonetix/include/df/bufio.h +++ b/lonetix/include/df/bufio.h @@ -172,14 +172,16 @@ FORCE_INLINE Sint64 Bufio_Putc(Stmwrbuf *sb, char c) * `nbytes`), -1 on error. */ Sint64 _Bufio_Putsn(Stmwrbuf *, const char *, size_t); +Sint64 _Bufio_SmallPutsn(Stmwrbuf *, const char *, size_t); #ifdef __GNUC__ // Optimize to call Bufio_Putc() if 'nbytes' is statically known to be 1 // NOTE: Avoids needless EOLN overhead on Unix -#define Bufio_Putsn(sb, s, nbytes) ( \ - (__builtin_constant_p(nbytes) && (nbytes) == 1) ? \ - Bufio_Putc(sb, (s)[0]) : \ - _Bufio_Putsn(sb, s, nbytes) \ +#define Bufio_Putsn(sb, s, nbytes) ( \ + (__builtin_constant_p(nbytes) && (nbytes) <= 64) ? \ + (((nbytes) == 1) ? Bufio_Putc(sb, (s)[0]) \ + : _Bufio_SmallPutsn(sb, s, nbytes)) \ + : _Bufio_Putsn(sb, s, nbytes) \ ) #else #define Bufio_Putsn(sb, s, nbytes) _Bufio_Putsn(sb, s, nbytes)