diff --git a/kern/main/menu.c b/kern/main/menu.c index 8905f09..1f5723a 100644 --- a/kern/main/menu.c +++ b/kern/main/menu.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include #include @@ -237,6 +239,21 @@ cmd_sync(int nargs, char **args) return 0; } +/* + * Command for dropping to the debugger. + */ +static +int +cmd_debug(int nargs, char **args) +{ + (void)nargs; + (void)args; + + mainbus_debugger(); + + return 0; +} + /* * Command for doing an intentional panic. */ @@ -251,6 +268,81 @@ cmd_panic(int nargs, char **args) return 0; } +/* + * Subthread for intentially deadlocking. + */ +struct deadlock { + struct lock *lock1; + struct lock *lock2; +}; + +static +void +cmd_deadlockthread(void *ptr, unsigned long num) +{ + struct deadlock *dl = ptr; + + (void)num; + + /* If it doesn't wedge right away, keep trying... */ + while (1) { + lock_acquire(dl->lock2); + lock_acquire(dl->lock1); + kprintf("+"); + lock_release(dl->lock1); + lock_release(dl->lock2); + } +} + +/* + * Command for doing an intentional deadlock. + */ +static +int +cmd_deadlock(int nargs, char **args) +{ + struct deadlock dl; + int result; + + (void)nargs; + (void)args; + + dl.lock1 = lock_create("deadlock1"); + if (dl.lock1 == NULL) { + kprintf("lock_create failed\n"); + return ENOMEM; + } + dl.lock2 = lock_create("deadlock2"); + if (dl.lock2 == NULL) { + lock_destroy(dl.lock1); + kprintf("lock_create failed\n"); + return ENOMEM; + } + + result = thread_fork(args[0] /* thread name */, + NULL /* kernel thread */, + cmd_deadlockthread /* thread function */, + &dl /* thread arg */, 0 /* thread arg */); + if (result) { + kprintf("thread_fork failed: %s\n", strerror(result)); + lock_release(dl.lock1); + lock_destroy(dl.lock2); + lock_destroy(dl.lock1); + return result; + } + + /* If it doesn't wedge right away, keep trying... */ + while (1) { + lock_acquire(dl.lock1); + lock_acquire(dl.lock2); + kprintf("."); + lock_release(dl.lock2); + lock_release(dl.lock1); + } + /* NOTREACHED */ + return 0; +} + /* * Command for shutting down. */ @@ -441,7 +533,9 @@ static const char *opsmenu[] = { "[cd] Change directory ", "[pwd] Print current directory ", "[sync] Sync filesystems ", + "[debug] Drop to debugger ", "[panic] Intentional panic ", + "[deadlock] Intentional deadlock ", "[q] Quit and shut down ", NULL }; @@ -547,7 +641,9 @@ static struct { { "cd", cmd_chdir }, { "pwd", cmd_pwd }, { "sync", cmd_sync }, + { "debug", cmd_debug }, { "panic", cmd_panic }, + { "deadlock", cmd_deadlock }, { "q", cmd_quit }, { "exit", cmd_quit }, { "halt", cmd_quit },