diff --git a/kern/include/test.h b/kern/include/test.h index 9445a5c..68f0c73 100644 --- a/kern/include/test.h +++ b/kern/include/test.h @@ -61,6 +61,8 @@ int semtest(int, char **); int locktest(int, char **); int locktest2(int, char **); int locktest3(int, char **); +int locktest4(int, char **); +int locktest5(int, char **); int cvtest(int, char **); int cvtest2(int, char **); int cvtest3(int, char **); @@ -156,7 +158,7 @@ void whalemating_cleanup(void); void male(uint32_t); void female(uint32_t); void matchmaker(uint32_t); - + /* * stoplight.c. */ diff --git a/kern/main/menu.c b/kern/main/menu.c index c104187..d9eaf2a 100644 --- a/kern/main/menu.c +++ b/kern/main/menu.c @@ -593,6 +593,8 @@ static const char *testmenu[] = { "[lt1] Lock test 1 (1) ", "[lt2] Lock test 2 (1*) ", "[lt3] Lock test 3 (1*) ", + "[lt4] Lock test 4 (1*) ", + "[lt5] Lock test 5 (1*) ", "[cvt1] CV test 1 (1) ", "[cvt2] CV test 2 (1) ", "[cvt3] CV test 3 (1*) ", @@ -743,6 +745,8 @@ static struct { { "lt1", locktest }, { "lt2", locktest2 }, { "lt3", locktest3 }, + { "lt4", locktest4 }, + { "lt5", locktest5 }, { "cvt1", cvtest }, { "cvt2", cvtest2 }, { "cvt3", cvtest3 }, diff --git a/kern/test/synchtest.c b/kern/test/synchtest.c index 23bb151..0639ddc 100644 --- a/kern/test/synchtest.c +++ b/kern/test/synchtest.c @@ -238,7 +238,6 @@ fail2: return; } - int locktest(int nargs, char **args) { @@ -289,6 +288,13 @@ locktest(int nargs, char **args) return 0; } +/* + * Note that the following tests that panic on success do minimal cleanup + * afterward. This is to avoid causing a panic that could be unintentiontally + * considered a success signal by test161. As a result, they leak memory, + * don't destroy synchronization primitives, etc. + */ + int locktest2(int nargs, char **args) { (void)nargs; @@ -309,9 +315,9 @@ locktest2(int nargs, char **args) { success(TEST161_FAIL, SECRET, "lt2"); - lock_destroy(testlock); - testlock = NULL; + /* Don't do anything that could panic. */ + testlock = NULL; return 0; } @@ -336,11 +342,110 @@ locktest3(int nargs, char **args) { success(TEST161_FAIL, SECRET, "lt3"); - testlock = NULL; + /* Don't do anything that could panic. */ + testlock = NULL; return 0; } +/* + * Used by both lt4 and lt5 below. Simply acquires a lock in a separate + * thread. Uses a semaphore as a barrier to make sure it gets the lock before + * the driver completes. + */ + +static +void +locktestacquirer(void * junk, unsigned long num) +{ + (void)junk; + (void)num; + + lock_acquire(testlock); + V(donesem); + + return; +} + + +int +locktest4(int nargs, char **args) { + (void) nargs; + (void) args; + + kprintf_n("Starting lt4...\n"); + kprintf_n("(This test panics on success!)\n"); + + testlock = lock_create("testlock"); + if (testlock == NULL) { + panic("lt4: lock_create failed\n"); + } + + donesem = sem_create("donesem", 0); + if (donesem == NULL) { + lock_destroy(testlock); + panic("lt4: sem_create failed\n"); + } + + result = thread_fork("lt4", NULL, locktestacquirer, NULL, 0); + if (result) { + panic("lt4: thread_fork failed: %s\n", strerror(result)); + } + + P(donesem); + secprintf(SECRET, "Should panic...", "lt4"); + lock_release(testlock); + + /* Should not get here on success. */ + + success(TEST161_FAIL, SECRET, "lt4"); + + /* Don't do anything that could panic. */ + + testlock = NULL; + donesem = NULL; + return 0; +} + +int +locktest5(int nargs, char **args) { + (void) nargs; + (void) args; + + kprintf_n("Starting lt5...\n"); + kprintf_n("(This test panics on success!)\n"); + + testlock = lock_create("testlock"); + if (testlock == NULL) { + panic("lt5: lock_create failed\n"); + } + + donesem = sem_create("donesem", 0); + if (donesem == NULL) { + lock_destroy(testlock); + panic("lt5: sem_create failed\n"); + } + + result = thread_fork("lt5", NULL, locktestacquirer, NULL, 0); + if (result) { + panic("lt5: thread_fork failed: %s\n", strerror(result)); + } + + P(donesem); + secprintf(SECRET, "Should panic...", "lt5"); + KASSERT(!(lock_do_i_hold(testlock))); + + /* Should not get here on success. */ + + success(TEST161_FAIL, SECRET, "lt5"); + + /* Don't do anything that could panic. */ + + testlock = NULL; + donesem = NULL; + return 0; +} + static void cvtestthread(void *junk, unsigned long num)