Date: Sat, 29 Jul 2006 23:56:59 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102750 for review Message-ID: <200607292356.k6TNuxFi069861@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102750 Change 102750 by jb@jb_freebsd2 on 2006/07/29 23:56:06 Add a method to write strings to the console, making them atomic by using a lock. On sun4v this is important because 32 processors potentially writing can generate complete gobbledy-gook if allowed to write on a character by character basis. This change ensures that a printf (for example) which formats it's string in a stack buffer can write the string uninterrupted. Strings like these generally have a new-line character at the end, so string writes via the new method will write the rest of the line with any other writes interleaved before it. Affected files ... .. //depot/projects/dtrace/src/sys/sun4v/sun4v/hvcons.c#2 edit Differences ... ==== //depot/projects/dtrace/src/sys/sun4v/sun4v/hvcons.c#2 (text+ko) ==== @@ -43,12 +43,12 @@ #include "opt_simulator.h" +#include <machine/atomic.h> #include <machine/resource.h> #include <machine/hypervisor_api.h> #define HVCN_POLL_FREQ 10 - static d_open_t hvcn_open; static d_close_t hvcn_close; @@ -76,22 +76,24 @@ static int alt_break_state; #endif +static int cons_lock; + static void hvcn_tty_start(struct tty *); static int hvcn_tty_param(struct tty *, struct termios *); static void hvcn_tty_stop(struct tty *, int); static void hvcn_timeout(void *); +void hvcn_rawputc(int); static cn_probe_t hvcnprobe; static cn_init_t hvcninit; static cn_getc_t hvcngetc; static cn_checkc_t hvcncheckc; static cn_putc_t hvcnputc; +static cn_puts_t hvcnputs; - CONS_DRIVER(hvcn, hvcnprobe, hvcninit, NULL, hvcngetc, - hvcncheckc, hvcnputc, NULL); + hvcncheckc, hvcnputc, hvcnputs, NULL); - static int hvcn_open(struct cdev *dev, int flag, int mode, struct thread *td) { @@ -126,6 +128,7 @@ int polltime; polltime = hz / HVCN_POLL_FREQ; +polltime = 100; if (polltime < 1) { polltime = 1; } @@ -239,14 +242,11 @@ return (-1); } - -static void -hvcnputc(struct consdev *cp, int c) +void +hvcn_rawputc(int c) { + int error = 0; - int error; - - error = 0; do { if (c == '\n') error = hv_cnputchar('\r'); @@ -256,6 +256,29 @@ } while (error == H_EWOULDBLOCK); } +static void +hvcnputs(struct consdev *cp, char *p, int num) +{ + int i; + + while (!atomic_cmpset_acq_int(&cons_lock, 0, 1)) + DELAY(100); + + for (i = 0; i < num; i++) + hvcn_rawputc(p[i]); + + atomic_store_rel_int(&cons_lock, 0); +} + + +static void +hvcnputc(struct consdev *cp, int c) +{ + char x = c & 0xff; + + hvcnputs(cp, &x, 1); +} + static int hvcn_tty_param(struct tty *tp, struct termios *t) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607292356.k6TNuxFi069861>