Add a printx lock
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 19 Sep 2016 15:38:31 +0000 (11:38 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 19 Sep 2016 15:38:31 +0000 (11:38 -0400)
When debugging and relying on printed output, if you have a process that is
spamming the console, it can be hard to see what the kernel is printing
out.

This lock is meant to be used in debugging.  If you have printx turned on,
(px from the monitor), then the console prints will be synchronized with
other uses of px_lock().

For instance, if you want to drop a backtrace at some point, you could do:

sys_foo():
if (some_condition && printx_on) {
px_lock();
backtrace_user_ctx(current, current_ctx);
px_unlock();
}

You'd never commit that blob of code, but it's useful when tracking down a
bug.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/kdebug.h
kern/src/devfs.c
kern/src/kdebug.c

index 25ee729..b3effb4 100644 (file)
@@ -77,3 +77,6 @@ void set_printx(int mode);
 
 void debug_addr_proc(struct proc *p, unsigned long addr);
 void debug_addr_pid(int pid, unsigned long addr);
+
+void px_lock(void);
+void px_unlock(void);
index 8e2af71..fde7351 100644 (file)
@@ -108,9 +108,12 @@ ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
        /* TODO: tty hack.  they are sending us an escape sequence, and the keyboard
         * would try to print it (which it can't do yet).  The hack is even dirtier
         * in that we only detect it if it is the first char, and we ignore
-        * everything else. */
-       if (t_buf[0] != '\033') /* 0x1b */
+        * everything else.  \033 is 0x1b. */
+       if (t_buf[0] != '\033') {
+               px_lock();
                cputbuf(t_buf, count);
+               px_unlock();
+       }
        if (p)
                user_memdup_free(p, t_buf);
        return count;
index 8756a41..4271dd0 100644 (file)
@@ -278,3 +278,15 @@ void backtrace_user_ctx(struct proc *p, struct user_context *ctx)
        backtrace_user_frame(get_user_ctx_pc(ctx), get_user_ctx_fp(ctx));
        pcpui->__lock_checking_enabled++;
 }
+
+static spinlock_t __px_lock = SPINLOCK_INITIALIZER_IRQSAVE;
+void px_lock(void)
+{
+       if (printx_on)
+               spin_lock_irqsave(&__px_lock);
+}
+void px_unlock(void)
+{
+       if (printx_on)
+               spin_unlock_irqsave(&__px_lock);
+}