diff options
author | Scott Long <scottl@FreeBSD.org> | 2017-02-28 18:25:06 +0000 |
---|---|---|
committer | Scott Long <scottl@FreeBSD.org> | 2017-02-28 18:25:06 +0000 |
commit | 388f3ce6c3fb0c2eeeeebe1e0af6d72f840de7fc (patch) | |
tree | 2348634f666de456fdc532561183758e6480b2e7 /sys/kern/subr_prf.c | |
parent | 6d9160409317733fd7cf140d8f33fe408e69ee40 (diff) | |
download | src-388f3ce6c3fb0c2eeeeebe1e0af6d72f840de7fc.tar.gz src-388f3ce6c3fb0c2eeeeebe1e0af6d72f840de7fc.zip |
Implement sbuf_prf(), which takes an sbuf and outputs it
to stdout in the non-kernel case and to the console+log
in the kernel case. For the kernel case it hooks the
putbuf() machinery underneath printf(9) so that the buffer
is written completely atomically and without a copy into
another temporary buffer. This is useful for fixing
compound console/log messages that become broken and
interleaved when multiple threads are competing for the
console.
Reviewed by: ken, imp
Sponsored by: Netflix
Notes
Notes:
svn path=/head/; revision=314397
Diffstat (limited to 'sys/kern/subr_prf.c')
-rw-r--r-- | sys/kern/subr_prf.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index e78863830c7b..cc38d17ac113 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -411,6 +411,23 @@ vprintf(const char *fmt, va_list ap) } static void +prf_putbuf(char *bufr, int flags, int pri) +{ + + if (flags & TOLOG) + msglogstr(bufr, pri, /*filter_cr*/1); + + if (flags & TOCONS) { + if ((panicstr == NULL) && (constty != NULL)) + msgbuf_addstr(&consmsgbuf, -1, + bufr, /*filter_cr*/ 0); + + if ((constty == NULL) ||(always_console_output)) + cnputs(bufr); + } +} + +static void putbuf(int c, struct putchar_arg *ap) { /* Check if no console output buffer was provided. */ @@ -431,18 +448,7 @@ putbuf(int c, struct putchar_arg *ap) /* Check if the buffer needs to be flushed. */ if (ap->remain == 2 || c == '\n') { - - if (ap->flags & TOLOG) - msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1); - - if (ap->flags & TOCONS) { - if ((panicstr == NULL) && (constty != NULL)) - msgbuf_addstr(&consmsgbuf, -1, - ap->p_bufr, /*filter_cr*/ 0); - - if ((constty == NULL) ||(always_console_output)) - cnputs(ap->p_bufr); - } + prf_putbuf(ap->p_bufr, ap->flags, ap->pri); ap->p_next = ap->p_bufr; ap->remain = ap->n_bufr; @@ -1221,3 +1227,19 @@ counted_warning(unsigned *counter, const char *msg) } } #endif + +#ifdef _KERNEL +void +sbuf_putbuf(struct sbuf *sb) +{ + + prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1); +} +#else +void +sbuf_putbuf(struct sbuf *sb) +{ + + printf("%s", sbuf_data(sb)); +} +#endif |