diff --git a/kern/conf/conf.kern b/kern/conf/conf.kern index 2fbfc0f..0338825 100644 --- a/kern/conf/conf.kern +++ b/kern/conf/conf.kern @@ -437,11 +437,13 @@ file test/synchtest.c file test/semunit.c file test/kmalloctest.c file test/fstest.c +file test/lib.c + optfile net test/nettest.c defoption synchprobs -optfile synchprobs synchprobs/whalemating.c -optfile synchprobs synchprobs/stoplight.c +optfile synchprobs test/whalemating.c +optfile synchprobs test/stoplight.c optfile synchprobs test/synchprobs.c defoption automationtest diff --git a/kern/include/lib.h b/kern/include/lib.h index fe8cb6d..7478ce6 100644 --- a/kern/include/lib.h +++ b/kern/include/lib.h @@ -194,16 +194,5 @@ void kprintf_bootstrap(void); #define DIVROUNDUP(a,b) (((a)+(b)-1)/(b)) #define ROUNDUP(a,b) (DIVROUNDUP(a,b)*b) -void random_yielder(uint32_t); -void random_spinner(uint32_t); - -/* - * Testing variants of kprintf. tprintf is silent during automated testing. - * sprintf prefixes the kernel secret to kprintf messages during automated - * testing. nprintf is not silent during automated testing. - */ - -int tkprintf(const char *format, ...) __PF(1,2); -int nkprintf(const char *format, ...) __PF(1,2); #endif /* _LIB_H_ */ diff --git a/kern/include/stdarg.h b/kern/include/stdarg.h index b341996..b4db313 100644 --- a/kern/include/stdarg.h +++ b/kern/include/stdarg.h @@ -62,7 +62,7 @@ typedef __va_list va_list; * or split the definition of va_list into another header file, none * of which seems entirely desirable. */ -int vkprintf(const char *fmt, va_list ap) __PF(1,0); +void vkprintf(const char *fmt, va_list ap) __PF(1,0); int vsnprintf(char *buf, size_t maxlen, const char *fmt, va_list ap) __PF(3,0); /* diff --git a/kern/include/synch.h b/kern/include/synch.h index e0f3fb0..fee3b07 100644 --- a/kern/include/synch.h +++ b/kern/include/synch.h @@ -44,10 +44,10 @@ * internally. */ struct semaphore { - char *sem_name; + char *sem_name; struct wchan *sem_wchan; struct spinlock sem_lock; - volatile unsigned sem_count; + volatile unsigned sem_count; }; struct semaphore *sem_create(const char *name, unsigned initial_count); @@ -56,7 +56,7 @@ void sem_destroy(struct semaphore *); /* * Operations (both atomic): * P (proberen): decrement count. If the count is 0, block until - * the count is 1 again before decrementing. + * the count is 1 again before decrementing. * V (verhogen): increment count. */ void P(struct semaphore *); @@ -73,9 +73,9 @@ void V(struct semaphore *); * (should be) made internally. */ struct lock { - char *lk_name; - // add what you need here - // (don't forget to mark things volatile as needed) + char *lk_name; + // add what you need here + // (don't forget to mark things volatile as needed) }; struct lock *lock_create(const char *name); @@ -84,11 +84,11 @@ void lock_destroy(struct lock *); /* * Operations: * lock_acquire - Get the lock. Only one thread can hold the lock at the - * same time. + * same time. * lock_release - Free the lock. Only the thread holding the lock may do - * this. + * this. * lock_do_i_hold - Return true if the current thread holds the lock; - * false otherwise. + * false otherwise. * * These operations must be atomic. You get to write them. */ @@ -112,9 +112,9 @@ bool lock_do_i_hold(struct lock *); */ struct cv { - char *cv_name; - // add what you need here - // (don't forget to mark things volatile as needed) + char *cv_name; + // add what you need here + // (don't forget to mark things volatile as needed) }; struct cv *cv_create(const char *name); @@ -122,8 +122,8 @@ void cv_destroy(struct cv *); /* * Operations: - * cv_wait - Release the supplied lock, go to sleep, and, after - * waking up again, re-acquire the lock. + * cv_wait - Release the supplied lock, go to sleep, and, after + * waking up again, re-acquire the lock. * cv_signal - Wake up one thread that's sleeping on this CV. * cv_broadcast - Wake up all threads sleeping on this CV. * diff --git a/kern/include/synchprobs.h b/kern/include/synchprobs.h deleted file mode 100644 index 1f87846..0000000 --- a/kern/include/synchprobs.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _SYNCHPROBS_H_ -#define _SYNCHPROBS_H_ - -/* - * Synchronization problem primitives. - */ - -/* - * whalemating.c. - */ - -void whalemating_init(void); -void whalemating_cleanup(void); -void male(void); -void female(void); -void matchmaker(void); - -/* - * stoplight.c. - */ - -void gostraight(uint32_t); -void turnleft(uint32_t); -void turnright(uint32_t); -void stoplight_init(void); -void stoplight_cleanup(void); - -#endif /* _SYNCHPROBS_H_ */ diff --git a/kern/include/test.h b/kern/include/test.h index 7b8c17a..f9041e8 100644 --- a/kern/include/test.h +++ b/kern/include/test.h @@ -30,6 +30,9 @@ #ifndef _TEST_H_ #define _TEST_H_ +/* Get __PF() for declaring printf-like functions. */ +#include + #include "opt-synchprobs.h" #include "opt-automationtest.h" @@ -126,6 +129,30 @@ void inQuadrant(int); void leaveIntersection(void); int stoplight(int, char **); +/* + * Synchronization problem primitives. + */ + +/* + * whalemating.c. + */ + +void whalemating_init(void); +void whalemating_cleanup(void); +void male(void); +void female(void); +void matchmaker(void); + +/* + * stoplight.c. + */ + +void gostraight(uint32_t); +void turnleft(uint32_t); +void turnright(uint32_t); +void stoplight_init(void); +void stoplight_cleanup(void); + #endif /* @@ -138,4 +165,16 @@ int ll1test(int, char **); int ll16test(int, char **); #endif +void random_yielder(uint32_t); +void random_spinner(uint32_t); + +/* + * Testing variants of kprintf. tprintf is silent during automated testing. + * sprintf prefixes the kernel secret to kprintf messages during automated + * testing. nprintf is not silent during automated testing. + */ + +int tkprintf(const char *format, ...) __PF(1,2); +int nkprintf(const char *format, ...) __PF(1,2); + #endif /* _TEST_H_ */ diff --git a/kern/lib/kprintf.c b/kern/lib/kprintf.c index 0a6fe90..e7264ab 100644 --- a/kern/lib/kprintf.c +++ b/kern/lib/kprintf.c @@ -40,6 +40,7 @@ #include // for vfs_sync() #include // for ltrace_stop() #include +#include /* Flags word for DEBUG() macro. */ @@ -93,9 +94,10 @@ console_send(void *junk, const char *data, size_t len) /* * kprintf and tprintf helper function. */ +static inline int -vkprintf(const char *fmt, va_list ap) +__kprintf(const char *fmt, va_list ap) { int chars; bool dolock; @@ -134,7 +136,7 @@ kprintf(const char *fmt, ...) va_list ap; va_start(ap, fmt); - chars = vkprintf(fmt, ap); + chars = __kprintf(fmt, ap); va_end(ap); return chars; @@ -154,7 +156,7 @@ tkprintf(const char *fmt, ...) } va_start(ap, fmt); - chars = vkprintf(fmt, ap); + chars = __kprintf(fmt, ap); va_end(ap); return chars; @@ -173,7 +175,7 @@ nkprintf(const char *fmt, ...) } va_start(ap, fmt); - chars = vkprintf(fmt, ap); + chars = __kprintf(fmt, ap); va_end(ap); return chars; diff --git a/kern/lib/misc.c b/kern/lib/misc.c index c22d88c..2388e1d 100644 --- a/kern/lib/misc.c +++ b/kern/lib/misc.c @@ -30,7 +30,6 @@ #include #include #include -#include /* * Like strdup, but calls kmalloc. @@ -61,27 +60,3 @@ strerror(int errcode) panic("Invalid error code %d\n", errcode); return NULL; } - -/* - * Helper functions used by testing and problem driver code - * to establish better mixtures of threads. - */ - -void -random_yielder(uint32_t max_yield_count) -{ - uint32_t i; - for (i = 0; i < random() % max_yield_count; i++) { - thread_yield(); - } -} - -void -random_spinner(uint32_t max_spin_count) -{ - uint32_t i; - volatile int spin; - for (i = 0; i < random() % max_spin_count; i++) { - spin += i; - } -} diff --git a/kern/test/lib.c b/kern/test/lib.c new file mode 100644 index 0000000..1521487 --- /dev/null +++ b/kern/test/lib.c @@ -0,0 +1,27 @@ +#include +#include +#include + +/* + * Helper functions used by testing and problem driver code + * to establish better mixtures of threads. + */ + +void +random_yielder(uint32_t max_yield_count) +{ + uint32_t i; + for (i = 0; i < random() % max_yield_count; i++) { + thread_yield(); + } +} + +void +random_spinner(uint32_t max_spin_count) +{ + uint32_t i; + volatile int spin; + for (i = 0; i < random() % max_spin_count; i++) { + spin += i; + } +} diff --git a/kern/synchprobs/stoplight.c b/kern/test/stoplight.c similarity index 99% rename from kern/synchprobs/stoplight.c rename to kern/test/stoplight.c index 239407a..2247b9a 100644 --- a/kern/synchprobs/stoplight.c +++ b/kern/test/stoplight.c @@ -68,7 +68,6 @@ #include #include #include -#include /* * Called by the driver during initialization. diff --git a/kern/test/synchprobs.c b/kern/test/synchprobs.c index 1b5eaeb..b6ac2bf 100644 --- a/kern/test/synchprobs.c +++ b/kern/test/synchprobs.c @@ -11,7 +11,6 @@ #include #include #include -#include #define PROBLEMS_MAX_YIELDER 16 #define PROBLEMS_MAX_SPINNER 8192 diff --git a/kern/synchprobs/whalemating.c b/kern/test/whalemating.c similarity index 99% rename from kern/synchprobs/whalemating.c rename to kern/test/whalemating.c index b74f82d..54f65af 100644 --- a/kern/synchprobs/whalemating.c +++ b/kern/test/whalemating.c @@ -39,7 +39,6 @@ #include #include #include -#include /* * Called by the driver during initialization. diff --git a/kern/thread/synch.c b/kern/thread/synch.c index b7a08d9..d083f4b 100644 --- a/kern/thread/synch.c +++ b/kern/thread/synch.c @@ -47,18 +47,18 @@ struct semaphore * sem_create(const char *name, unsigned initial_count) { - struct semaphore *sem; + struct semaphore *sem; - sem = kmalloc(sizeof(*sem)); - if (sem == NULL) { - return NULL; - } + sem = kmalloc(sizeof(*sem)); + if (sem == NULL) { + return NULL; + } - sem->sem_name = kstrdup(name); - if (sem->sem_name == NULL) { - kfree(sem); - return NULL; - } + sem->sem_name = kstrdup(name); + if (sem->sem_name == NULL) { + kfree(sem); + return NULL; + } sem->sem_wchan = wchan_create(sem->sem_name); if (sem->sem_wchan == NULL) { @@ -68,39 +68,39 @@ sem_create(const char *name, unsigned initial_count) } spinlock_init(&sem->sem_lock); - sem->sem_count = initial_count; + sem->sem_count = initial_count; - return sem; + return sem; } void sem_destroy(struct semaphore *sem) { - KASSERT(sem != NULL); + KASSERT(sem != NULL); /* wchan_cleanup will assert if anyone's waiting on it */ spinlock_cleanup(&sem->sem_lock); wchan_destroy(sem->sem_wchan); - kfree(sem->sem_name); - kfree(sem); + kfree(sem->sem_name); + kfree(sem); } void P(struct semaphore *sem) { - KASSERT(sem != NULL); + KASSERT(sem != NULL); - /* - * May not block in an interrupt handler. - * - * For robustness, always check, even if we can actually - * complete the P without blocking. - */ - KASSERT(curthread->t_in_interrupt == false); + /* + * May not block in an interrupt handler. + * + * For robustness, always check, even if we can actually + * complete the P without blocking. + */ + KASSERT(curthread->t_in_interrupt == false); /* Use the semaphore spinlock to protect the wchan as well. */ spinlock_acquire(&sem->sem_lock); - while (sem->sem_count == 0) { + while (sem->sem_count == 0) { /* * * Note that we don't maintain strict FIFO ordering of @@ -114,21 +114,21 @@ P(struct semaphore *sem) * ordering? */ wchan_sleep(sem->sem_wchan, &sem->sem_lock); - } - KASSERT(sem->sem_count > 0); - sem->sem_count--; + } + KASSERT(sem->sem_count > 0); + sem->sem_count--; spinlock_release(&sem->sem_lock); } void V(struct semaphore *sem) { - KASSERT(sem != NULL); + KASSERT(sem != NULL); spinlock_acquire(&sem->sem_lock); - sem->sem_count++; - KASSERT(sem->sem_count > 0); + sem->sem_count++; + KASSERT(sem->sem_count > 0); wchan_wakeone(sem->sem_wchan, &sem->sem_lock); spinlock_release(&sem->sem_lock); @@ -141,59 +141,59 @@ V(struct semaphore *sem) struct lock * lock_create(const char *name) { - struct lock *lock; + struct lock *lock; - lock = kmalloc(sizeof(*lock)); - if (lock == NULL) { - return NULL; - } + lock = kmalloc(sizeof(*lock)); + if (lock == NULL) { + return NULL; + } - lock->lk_name = kstrdup(name); - if (lock->lk_name == NULL) { - kfree(lock); - return NULL; - } + lock->lk_name = kstrdup(name); + if (lock->lk_name == NULL) { + kfree(lock); + return NULL; + } - // add stuff here as needed + // add stuff here as needed - return lock; + return lock; } void lock_destroy(struct lock *lock) { - KASSERT(lock != NULL); + KASSERT(lock != NULL); - // add stuff here as needed + // add stuff here as needed - kfree(lock->lk_name); - kfree(lock); + kfree(lock->lk_name); + kfree(lock); } void lock_acquire(struct lock *lock) { - // Write this + // Write this - (void)lock; // suppress warning until code gets written + (void)lock; // suppress warning until code gets written } void lock_release(struct lock *lock) { - // Write this + // Write this - (void)lock; // suppress warning until code gets written + (void)lock; // suppress warning until code gets written } bool lock_do_i_hold(struct lock *lock) { - // Write this + // Write this - (void)lock; // suppress warning until code gets written + (void)lock; // suppress warning until code gets written - return true; // dummy until code gets written + return true; // dummy until code gets written } //////////////////////////////////////////////////////////// @@ -204,47 +204,47 @@ lock_do_i_hold(struct lock *lock) struct cv * cv_create(const char *name) { - struct cv *cv; + struct cv *cv; - cv = kmalloc(sizeof(*cv)); - if (cv == NULL) { - return NULL; - } + cv = kmalloc(sizeof(*cv)); + if (cv == NULL) { + return NULL; + } - cv->cv_name = kstrdup(name); - if (cv->cv_name==NULL) { - kfree(cv); - return NULL; - } + cv->cv_name = kstrdup(name); + if (cv->cv_name==NULL) { + kfree(cv); + return NULL; + } - // add stuff here as needed + // add stuff here as needed - return cv; + return cv; } void cv_destroy(struct cv *cv) { - KASSERT(cv != NULL); + KASSERT(cv != NULL); - // add stuff here as needed + // add stuff here as needed - kfree(cv->cv_name); - kfree(cv); + kfree(cv->cv_name); + kfree(cv); } void cv_wait(struct cv *cv, struct lock *lock) { - // Write this - (void)cv; // suppress warning until code gets written - (void)lock; // suppress warning until code gets written + // Write this + (void)cv; // suppress warning until code gets written + (void)lock; // suppress warning until code gets written } void cv_signal(struct cv *cv, struct lock *lock) { - // Write this + // Write this (void)cv; // suppress warning until code gets written (void)lock; // suppress warning until code gets written }