aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/subr_prf.c
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2017-02-28 18:25:06 +0000
committerScott Long <scottl@FreeBSD.org>2017-02-28 18:25:06 +0000
commit388f3ce6c3fb0c2eeeeebe1e0af6d72f840de7fc (patch)
tree2348634f666de456fdc532561183758e6480b2e7 /sys/kern/subr_prf.c
parent6d9160409317733fd7cf140d8f33fe408e69ee40 (diff)
downloadsrc-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.c46
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