Menu changes and test fixes for ASST1.
This commit is contained in:
		| @@ -59,6 +59,8 @@ int threadtest2(int, char **); | ||||
| int threadtest3(int, char **); | ||||
| int semtest(int, char **); | ||||
| int locktest(int, char **); | ||||
| int locktest2(int, char **); | ||||
| int locktest3(int, char **); | ||||
| int cvtest(int, char **); | ||||
| int cvtest2(int, char **); | ||||
| int rwtest(int, char **); | ||||
|   | ||||
| @@ -475,14 +475,16 @@ static const char *testmenu[] = { | ||||
| #if OPT_NET | ||||
| 	"[net] Network test                  ", | ||||
| #endif | ||||
| 	"[sy1] Semaphore test                ", | ||||
| 	"[sy2] Lock test             (1)     ", | ||||
| 	"[sy3] CV test               (1)     ", | ||||
| 	"[sy4] CV test #2            (1)     ", | ||||
| 	"[sy5] RW lock test          (1)     ", | ||||
| 	"[sem1] Semaphore test               ", | ||||
| 	"[lt1]  Lock test 1           (1)    ", | ||||
| 	"[lt2]  Lock test 2 (panics)  (1)    ", | ||||
| 	"[lt3]  Lock test 3 (panics)  (1)    ", | ||||
| 	"[cvt1] CV test 1             (1)    ", | ||||
| 	"[cvt2] CV test 2             (1)    ", | ||||
| 	"[rwt1] RW lock test          (1)    ", | ||||
| #if OPT_SYNCHPROBS | ||||
| 	"[sp1] Whalemating test      (1)     ", | ||||
| 	"[sp2] Stoplight test        (1)     ", | ||||
| 	"[sp1] Whalemating test       (1)    ", | ||||
| 	"[sp2] Stoplight test         (1)    ", | ||||
| #endif | ||||
| 	"[semu1-22] Semaphore unit tests     ", | ||||
| 	"[fs1] Filesystem test               ", | ||||
| @@ -607,13 +609,15 @@ static struct { | ||||
| 	{ "tt1",	threadtest }, | ||||
| 	{ "tt2",	threadtest2 }, | ||||
| 	{ "tt3",	threadtest3 }, | ||||
| 	{ "sy1",	semtest }, | ||||
|  | ||||
| 	/* synchronization assignment tests */ | ||||
| 	{ "sy2",	locktest }, | ||||
| 	{ "sy3",	cvtest }, | ||||
| 	{ "sy4",	cvtest2 }, | ||||
| 	{ "sy5",	rwtest }, | ||||
| 	{ "sem1",	semtest }, | ||||
| 	{ "lt1",	locktest }, | ||||
| 	{ "lt2",	locktest2 }, | ||||
| 	{ "lt3",	locktest3 }, | ||||
| 	{ "cvt1",	cvtest }, | ||||
| 	{ "cvt2",	cvtest2 }, | ||||
| 	{ "rwt1",	rwtest }, | ||||
| #if OPT_SYNCHPROBS | ||||
| 	{ "sp1",	whalemating }, | ||||
| 	{ "sp2",	stoplight }, | ||||
|   | ||||
| @@ -40,75 +40,47 @@ | ||||
| #include <kern/secret.h> | ||||
| #include <spinlock.h> | ||||
|  | ||||
| #define CREATELOOPS		8 | ||||
| #define NSEMLOOPS     63 | ||||
| #define NLOCKLOOPS    120 | ||||
| #define NCVLOOPS      5 | ||||
| #define NTHREADS      32 | ||||
| #define SYNCHTEST_YIELDER_MAX 16 | ||||
|  | ||||
| static volatile unsigned long testval1; | ||||
| static volatile unsigned long testval2; | ||||
| static volatile unsigned long testval3; | ||||
| static volatile int32_t testval4; | ||||
|  | ||||
| static struct semaphore *testsem; | ||||
| static struct lock *testlock; | ||||
| static struct cv *testcv; | ||||
| static struct semaphore *donesem; | ||||
| static struct semaphore *testsem = NULL; | ||||
| static struct lock *testlock = NULL; | ||||
| static struct cv *testcv = NULL; | ||||
| static struct semaphore *donesem = NULL; | ||||
|  | ||||
| struct spinlock status_lock; | ||||
| static bool test_status; | ||||
| static bool test_status = FAIL; | ||||
|  | ||||
| static unsigned long semtest_current; | ||||
|  | ||||
| static | ||||
| void | ||||
| inititems(void) | ||||
| { | ||||
| 	if (testsem==NULL) { | ||||
| 		testsem = sem_create("testsem", 2); | ||||
| 		if (testsem == NULL) { | ||||
| 			panic("synchtest: sem_create failed\n"); | ||||
| 		} | ||||
| 	} | ||||
| 	if (testlock==NULL) { | ||||
| 		testlock = lock_create("testlock"); | ||||
| 		if (testlock == NULL) { | ||||
| 			panic("synchtest: lock_create failed\n"); | ||||
| 		} | ||||
| 	} | ||||
| 	if (testcv==NULL) { | ||||
| 		testcv = cv_create("testlock"); | ||||
| 		if (testcv == NULL) { | ||||
| 			panic("synchtest: cv_create failed\n"); | ||||
| 		} | ||||
| 	} | ||||
| 	if (donesem==NULL) { | ||||
| 		donesem = sem_create("donesem", 0); | ||||
| 		if (donesem == NULL) { | ||||
| 			panic("synchtest: sem_create failed\n"); | ||||
| 		} | ||||
| 	} | ||||
| 	spinlock_init(&status_lock); | ||||
| } | ||||
|  | ||||
|  | ||||
| static | ||||
| void | ||||
| semtestthread(void *junk, unsigned long num) | ||||
| { | ||||
| 	int i; | ||||
| 	(void)junk; | ||||
|  | ||||
| 	int i; | ||||
| 	 | ||||
| 	random_yielder(4); | ||||
|  | ||||
| 	/* | ||||
| 	 * Only one of these should print at a time. | ||||
| 	 */ | ||||
| 	random_yielder(4); | ||||
| 	P(testsem); | ||||
| 	semtest_current = num; | ||||
| 	kprintf_n("Thread %2lu: ", num); | ||||
|  | ||||
| 	kprintf_n("Thread %2lu: ", num); | ||||
| 	for (i=0; i<NSEMLOOPS; i++) { | ||||
| 		kprintf_n("%c", (int)num+64); | ||||
| 		kprintf_n("%2lu", num); | ||||
| 		random_yielder(4); | ||||
| 		if (semtest_current != num) { | ||||
| 			spinlock_acquire(&status_lock); | ||||
| @@ -116,75 +88,71 @@ semtestthread(void *junk, unsigned long num) | ||||
| 			spinlock_release(&status_lock); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	kprintf_n("\n"); | ||||
|  | ||||
| 	V(donesem); | ||||
| } | ||||
|  | ||||
| int | ||||
| semtest(int nargs, char **args) | ||||
| { | ||||
| 	int i, result; | ||||
|  | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	inititems(); | ||||
| 	int i, result; | ||||
| 	 | ||||
| 	kprintf_n("Starting sem1...\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		testsem = sem_create("testsem", 2); | ||||
| 		if (testsem == NULL) { | ||||
| 			panic("sem1: sem_create failed\n"); | ||||
| 		} | ||||
| 		donesem = sem_create("donesem", 0); | ||||
| 		if (donesem == NULL) { | ||||
| 			panic("sem1: sem_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			sem_destroy(testsem); | ||||
| 			sem_destroy(donesem); | ||||
| 		} | ||||
| 	} | ||||
| 	test_status = FAIL; | ||||
| 	kprintf_n("Starting semaphore test...\n"); | ||||
|  | ||||
| 	kprintf_n("If this hangs, it's broken: "); | ||||
| 	P(testsem); | ||||
| 	P(testsem); | ||||
| 	kprintf_n("OK\n"); | ||||
| 	test_status = SUCCESS; | ||||
| 	kprintf_n("ok\n"); | ||||
|  | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		result = thread_fork("semtest", NULL, semtestthread, NULL, i); | ||||
| 		if (result) { | ||||
| 			panic("semtest: thread_fork failed: %s\n", | ||||
| 			panic("sem1: thread_fork failed: %s\n", | ||||
| 			      strerror(result)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		V(testsem); | ||||
| 		P(donesem); | ||||
| 	} | ||||
|  | ||||
| 	/* so we can run it again */ | ||||
| 	V(testsem); | ||||
| 	V(testsem); | ||||
| 	sem_destroy(testsem); | ||||
| 	sem_destroy(donesem); | ||||
| 	testsem = donesem = NULL; | ||||
| 	 | ||||
| 	kprintf_n("Semaphore test done.\n"); | ||||
| 	success(test_status, SECRET, "sy1"); | ||||
| 	success(test_status, SECRET, "sem1"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static | ||||
| void | ||||
| fail(unsigned long num, const char *msg) | ||||
| { | ||||
| 	kprintf_n("thread %lu: Mismatch on %s\n", num, msg); | ||||
| 	kprintf_n("Test failed\n"); | ||||
|  | ||||
| 	lock_release(testlock); | ||||
|  | ||||
| 	spinlock_acquire(&status_lock); | ||||
| 	test_status = FAIL; | ||||
| 	spinlock_release(&status_lock); | ||||
|  | ||||
| 	V(donesem); | ||||
| 	thread_exit(); | ||||
| } | ||||
|  | ||||
| static | ||||
| void | ||||
| locktestthread(void *junk, unsigned long num) | ||||
| { | ||||
| 	int i; | ||||
| 	(void)junk; | ||||
|  | ||||
| 	int i; | ||||
|  | ||||
| 	for (i=0; i<NLOCKLOOPS; i++) { | ||||
| 		lock_acquire(testlock); | ||||
| 		random_yielder(4); | ||||
| @@ -194,65 +162,163 @@ locktestthread(void *junk, unsigned long num) | ||||
| 		testval3 = num%3; | ||||
|  | ||||
| 		if (testval2 != testval1*testval1) { | ||||
| 			fail(num, "testval2/testval1"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		if (testval2%3 != (testval3*testval3)%3) { | ||||
| 			fail(num, "testval2/testval3"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		if (testval3 != testval1%3) { | ||||
| 			fail(num, "testval3/testval1"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		if (testval1 != num) { | ||||
| 			fail(num, "testval1/num"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		if (testval2 != num*num) { | ||||
| 			fail(num, "testval2/num"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		if (testval3 != num%3) { | ||||
| 			fail(num, "testval3/num"); | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
| 		 | ||||
| 		if (!(lock_do_i_hold(testlock))) { | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		random_yielder(4); | ||||
|  | ||||
| 		lock_release(testlock); | ||||
| 	} | ||||
| 	 | ||||
| 	/* Check for solutions that don't track ownership properly */ | ||||
|  | ||||
| 	for (i=0; i<NLOCKLOOPS; i++) { | ||||
| 		if (lock_do_i_hold(testlock)) { | ||||
| 			goto fail2; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	V(donesem); | ||||
| 	return; | ||||
|  | ||||
| fail: | ||||
| 	lock_release(testlock); | ||||
| fail2: | ||||
| 	spinlock_acquire(&status_lock); | ||||
| 	test_status = FAIL; | ||||
| 	spinlock_release(&status_lock); | ||||
| 	V(donesem); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| locktest(int nargs, char **args) | ||||
| { | ||||
| 	int i, result; | ||||
|  | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	inititems(); | ||||
| 	int i, result; | ||||
| 	 | ||||
| 	kprintf_n("Starting lt1...\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		testlock = lock_create("testlock"); | ||||
| 		if (testlock == NULL) { | ||||
| 			panic("lt1: lock_create failed\n"); | ||||
| 		} | ||||
| 		donesem = sem_create("donesem", 0); | ||||
| 		if (donesem == NULL) { | ||||
| 			panic("lt1: sem_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			lock_destroy(testlock); | ||||
| 			sem_destroy(donesem); | ||||
| 		} | ||||
| 	} | ||||
| 	test_status = SUCCESS; | ||||
| 	kprintf_n("Starting lock test...\n"); | ||||
|  | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		result = thread_fork("synchtest", NULL, locktestthread, NULL, i); | ||||
| 		if (result) { | ||||
| 			panic("locktest: thread_fork failed: %s\n", strerror(result)); | ||||
| 			panic("lt1: thread_fork failed: %s\n", strerror(result)); | ||||
| 		} | ||||
| 	} | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		P(donesem); | ||||
| 	} | ||||
| 	 | ||||
| 	kprintf_n("Lock test done.\n"); | ||||
| 	success(test_status, SECRET, "sy2"); | ||||
| 	lock_destroy(testlock); | ||||
| 	sem_destroy(donesem); | ||||
| 	testlock = NULL; | ||||
| 	donesem = NULL; | ||||
|  | ||||
| 	success(test_status, SECRET, "lt1"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| locktest2(int nargs, char **args) { | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	int i; | ||||
| 	 | ||||
| 	kprintf_n("Starting lt2...\n"); | ||||
| 	kprintf_n("(This test panics on success!)\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		testlock = lock_create("testlock"); | ||||
| 		if (testlock == NULL) { | ||||
| 			panic("lt2: lock_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			lock_destroy(testlock); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	success(SUCCESS, SECRET, "lt2"); | ||||
| 	lock_release(testlock); | ||||
| 	/* Should not get here on success. */ | ||||
| 	success(FAIL, SECRET, "lt2"); | ||||
| 	testlock = NULL; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| locktest3(int nargs, char **args) { | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
| 	 | ||||
| 	int i; | ||||
| 	 | ||||
| 	kprintf_n("Starting lt3...\n"); | ||||
| 	kprintf_n("(This test panics on success!){\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		testlock = lock_create("testlock"); | ||||
| 		if (testlock == NULL) { | ||||
| 			panic("lt3: lock_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			lock_destroy(testlock); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	success(SUCCESS, SECRET, "lt3"); | ||||
| 	lock_acquire(testlock); | ||||
| 	lock_destroy(testlock); | ||||
| 	/* Should not get here on success. */ | ||||
| 	success(FAIL, SECRET, "lt3"); | ||||
| 	testlock = NULL; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -261,12 +327,12 @@ static | ||||
| void | ||||
| cvtestthread(void *junk, unsigned long num) | ||||
| { | ||||
| 	(void)junk; | ||||
|  | ||||
| 	int i; | ||||
| 	volatile int j; | ||||
| 	struct timespec ts1, ts2; | ||||
|  | ||||
| 	(void)junk; | ||||
|  | ||||
| 	for (i=0; i<NCVLOOPS; i++) { | ||||
| 		lock_acquire(testlock); | ||||
| 		while (testval1 != num) { | ||||
| @@ -321,29 +387,52 @@ cvtestthread(void *junk, unsigned long num) | ||||
| int | ||||
| cvtest(int nargs, char **args) | ||||
| { | ||||
| 	int i, result; | ||||
|  | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	inititems(); | ||||
| 	kprintf_n("Starting CV test...\n"); | ||||
| 	kprintf_n("Threads should print out in reverse order.\n"); | ||||
| 	 | ||||
| 	int i, result; | ||||
| 	 | ||||
| 	kprintf_n("Starting cvt1...\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		testlock = lock_create("testlock"); | ||||
| 		if (testlock == NULL) { | ||||
| 			panic("lockt1: lock_create failed\n"); | ||||
| 		} | ||||
| 		testcv = cv_create("testcv"); | ||||
| 		if (testcv == NULL) { | ||||
| 			panic("cvt1: cv_create failed\n"); | ||||
| 		} | ||||
| 		donesem = sem_create("donesem", 0); | ||||
| 		if (donesem == NULL) { | ||||
| 			panic("cvt1: sem_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			lock_destroy(testlock); | ||||
| 			cv_destroy(testcv); | ||||
| 			sem_destroy(donesem); | ||||
| 		} | ||||
| 	} | ||||
| 	test_status = SUCCESS; | ||||
|  | ||||
| 	testval1 = NTHREADS-1; | ||||
|  | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		result = thread_fork("synchtest", NULL, cvtestthread, NULL, (long unsigned) i); | ||||
| 		result = thread_fork("cvt1", NULL, cvtestthread, NULL, (long unsigned) i); | ||||
| 		if (result) { | ||||
| 			panic("cvtest: thread_fork failed: %s\n", strerror(result)); | ||||
| 			panic("cvt1: thread_fork failed: %s\n", strerror(result)); | ||||
| 		} | ||||
| 	} | ||||
| 	for (i=0; i<NTHREADS; i++) { | ||||
| 		P(donesem); | ||||
| 	} | ||||
| 	 | ||||
| 	kprintf_n("CV test done\n"); | ||||
| 	success(test_status, SECRET, "sy3"); | ||||
| 	lock_destroy(testlock); | ||||
| 	cv_destroy(testcv); | ||||
| 	sem_destroy(donesem); | ||||
| 	testlock = NULL; | ||||
| 	testcv = NULL; | ||||
| 	donesem = NULL; | ||||
| 	 | ||||
| 	success(test_status, SECRET, "cvt1"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -369,10 +458,10 @@ static | ||||
| void | ||||
| sleepthread(void *junk1, unsigned long junk2) | ||||
| { | ||||
| 	unsigned i, j; | ||||
|  | ||||
| 	(void)junk1; | ||||
| 	(void)junk2; | ||||
|  | ||||
| 	unsigned i, j; | ||||
| 	 | ||||
| 	random_yielder(4); | ||||
|  | ||||
| @@ -398,11 +487,11 @@ static | ||||
| void | ||||
| wakethread(void *junk1, unsigned long junk2) | ||||
| { | ||||
| 	unsigned i, j; | ||||
|  | ||||
| 	(void)junk1; | ||||
| 	(void)junk2; | ||||
|  | ||||
| 	unsigned i, j; | ||||
|  | ||||
| 	random_yielder(4); | ||||
|  | ||||
| 	for (j=0; j<NLOOPS; j++) { | ||||
| @@ -430,33 +519,41 @@ wakethread(void *junk1, unsigned long junk2) | ||||
| int | ||||
| cvtest2(int nargs, char **args) | ||||
| { | ||||
| 	unsigned i; | ||||
| 	int result; | ||||
|  | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
| 	 | ||||
| 	inititems(); | ||||
| 	test_status = SUCCESS; | ||||
| 	unsigned i; | ||||
| 	int result; | ||||
|  | ||||
| 	kprintf_n("Starting cvt2...\n"); | ||||
| 	for (i=0; i<CREATELOOPS; i++) { | ||||
| 		gatesem = sem_create("gatesem", 0); | ||||
| 		if (gatesem == NULL) { | ||||
| 			panic("cvt2: sem_create failed\n"); | ||||
| 		} | ||||
| 		exitsem = sem_create("exitsem", 0); | ||||
| 		if (exitsem == NULL) { | ||||
| 			panic("cvt2: sem_create failed\n"); | ||||
| 		} | ||||
| 		if (i != CREATELOOPS - 1) { | ||||
| 			sem_destroy(gatesem); | ||||
| 			sem_destroy(exitsem); | ||||
| 		} | ||||
| 	} | ||||
| 	for (i=0; i<NCVS; i++) { | ||||
| 		testlocks[i] = lock_create("cvtest2 lock"); | ||||
| 		testcvs[i] = cv_create("cvtest2 cv"); | ||||
| 	} | ||||
| 	gatesem = sem_create("gatesem", 0); | ||||
| 	exitsem = sem_create("exitsem", 0); | ||||
| 	test_status = SUCCESS; | ||||
|  | ||||
| 	kprintf_n("cvtest2...\n"); | ||||
|  | ||||
| 	result = thread_fork("cvtest2", NULL, sleepthread, NULL, 0); | ||||
| 	result = thread_fork("cvt2", NULL, sleepthread, NULL, 0); | ||||
| 	if (result) { | ||||
| 		panic("cvtest2: thread_fork failed\n"); | ||||
| 		panic("cvt2: thread_fork failed\n"); | ||||
| 	} | ||||
| 	result = thread_fork("cvtest2", NULL, wakethread, NULL, 0); | ||||
| 	result = thread_fork("cvt2", NULL, wakethread, NULL, 0); | ||||
| 	if (result) { | ||||
| 		panic("cvtest2: thread_fork failed\n"); | ||||
| 		panic("cvt2: thread_fork failed\n"); | ||||
| 	} | ||||
|  | ||||
| 	P(exitsem); | ||||
| 	P(exitsem); | ||||
|  | ||||
| @@ -470,23 +567,18 @@ cvtest2(int nargs, char **args) | ||||
| 		testcvs[i] = NULL; | ||||
| 	} | ||||
|  | ||||
| 	kprintf_n("cvtest2 done\n"); | ||||
| 	success(test_status, SECRET, "sy4"); | ||||
| 	success(test_status, SECRET, "cvt2"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Complete this for ASST1. | ||||
|  */ | ||||
|  | ||||
| int rwtest(int nargs, char **args) { | ||||
| 	 | ||||
| 	(void) nargs; | ||||
| 	(void) args; | ||||
| 	 | ||||
| 	kprintf_n("rwtest unimplemented\n"); | ||||
| 	success(FAIL, SECRET, "sy5"); | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	kprintf_n("rwt1 unimplemented\n"); | ||||
| 	success(FAIL, SECRET, "rwt1"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user