Trying to get closer to the original OS/161 sources.
This commit is contained in:
parent
202cc3eab4
commit
a6878c822b
@ -437,11 +437,13 @@ file test/synchtest.c
|
|||||||
file test/semunit.c
|
file test/semunit.c
|
||||||
file test/kmalloctest.c
|
file test/kmalloctest.c
|
||||||
file test/fstest.c
|
file test/fstest.c
|
||||||
|
file test/lib.c
|
||||||
|
|
||||||
optfile net test/nettest.c
|
optfile net test/nettest.c
|
||||||
|
|
||||||
defoption synchprobs
|
defoption synchprobs
|
||||||
optfile synchprobs synchprobs/whalemating.c
|
optfile synchprobs test/whalemating.c
|
||||||
optfile synchprobs synchprobs/stoplight.c
|
optfile synchprobs test/stoplight.c
|
||||||
optfile synchprobs test/synchprobs.c
|
optfile synchprobs test/synchprobs.c
|
||||||
|
|
||||||
defoption automationtest
|
defoption automationtest
|
||||||
|
@ -194,16 +194,5 @@ void kprintf_bootstrap(void);
|
|||||||
#define DIVROUNDUP(a,b) (((a)+(b)-1)/(b))
|
#define DIVROUNDUP(a,b) (((a)+(b)-1)/(b))
|
||||||
#define ROUNDUP(a,b) (DIVROUNDUP(a,b)*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_ */
|
#endif /* _LIB_H_ */
|
||||||
|
@ -62,7 +62,7 @@ typedef __va_list va_list;
|
|||||||
* or split the definition of va_list into another header file, none
|
* or split the definition of va_list into another header file, none
|
||||||
* of which seems entirely desirable.
|
* 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);
|
int vsnprintf(char *buf, size_t maxlen, const char *fmt, va_list ap) __PF(3,0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,10 +44,10 @@
|
|||||||
* internally.
|
* internally.
|
||||||
*/
|
*/
|
||||||
struct semaphore {
|
struct semaphore {
|
||||||
char *sem_name;
|
char *sem_name;
|
||||||
struct wchan *sem_wchan;
|
struct wchan *sem_wchan;
|
||||||
struct spinlock sem_lock;
|
struct spinlock sem_lock;
|
||||||
volatile unsigned sem_count;
|
volatile unsigned sem_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct semaphore *sem_create(const char *name, unsigned initial_count);
|
struct semaphore *sem_create(const char *name, unsigned initial_count);
|
||||||
@ -56,7 +56,7 @@ void sem_destroy(struct semaphore *);
|
|||||||
/*
|
/*
|
||||||
* Operations (both atomic):
|
* Operations (both atomic):
|
||||||
* P (proberen): decrement count. If the count is 0, block until
|
* 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.
|
* V (verhogen): increment count.
|
||||||
*/
|
*/
|
||||||
void P(struct semaphore *);
|
void P(struct semaphore *);
|
||||||
@ -73,9 +73,9 @@ void V(struct semaphore *);
|
|||||||
* (should be) made internally.
|
* (should be) made internally.
|
||||||
*/
|
*/
|
||||||
struct lock {
|
struct lock {
|
||||||
char *lk_name;
|
char *lk_name;
|
||||||
// add what you need here
|
// add what you need here
|
||||||
// (don't forget to mark things volatile as needed)
|
// (don't forget to mark things volatile as needed)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lock *lock_create(const char *name);
|
struct lock *lock_create(const char *name);
|
||||||
@ -84,11 +84,11 @@ void lock_destroy(struct lock *);
|
|||||||
/*
|
/*
|
||||||
* Operations:
|
* Operations:
|
||||||
* lock_acquire - Get the lock. Only one thread can hold the lock at the
|
* 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
|
* 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;
|
* 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.
|
* These operations must be atomic. You get to write them.
|
||||||
*/
|
*/
|
||||||
@ -112,9 +112,9 @@ bool lock_do_i_hold(struct lock *);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct cv {
|
struct cv {
|
||||||
char *cv_name;
|
char *cv_name;
|
||||||
// add what you need here
|
// add what you need here
|
||||||
// (don't forget to mark things volatile as needed)
|
// (don't forget to mark things volatile as needed)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cv *cv_create(const char *name);
|
struct cv *cv_create(const char *name);
|
||||||
@ -122,8 +122,8 @@ void cv_destroy(struct cv *);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Operations:
|
* Operations:
|
||||||
* cv_wait - Release the supplied lock, go to sleep, and, after
|
* cv_wait - Release the supplied lock, go to sleep, and, after
|
||||||
* waking up again, re-acquire the lock.
|
* waking up again, re-acquire the lock.
|
||||||
* cv_signal - Wake up one thread that's sleeping on this CV.
|
* cv_signal - Wake up one thread that's sleeping on this CV.
|
||||||
* cv_broadcast - Wake up all threads sleeping on this CV.
|
* cv_broadcast - Wake up all threads sleeping on this CV.
|
||||||
*
|
*
|
||||||
|
@ -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_ */
|
|
@ -30,6 +30,9 @@
|
|||||||
#ifndef _TEST_H_
|
#ifndef _TEST_H_
|
||||||
#define _TEST_H_
|
#define _TEST_H_
|
||||||
|
|
||||||
|
/* Get __PF() for declaring printf-like functions. */
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
#include "opt-synchprobs.h"
|
#include "opt-synchprobs.h"
|
||||||
#include "opt-automationtest.h"
|
#include "opt-automationtest.h"
|
||||||
|
|
||||||
@ -126,6 +129,30 @@ void inQuadrant(int);
|
|||||||
void leaveIntersection(void);
|
void leaveIntersection(void);
|
||||||
int stoplight(int, char **);
|
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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -138,4 +165,16 @@ int ll1test(int, char **);
|
|||||||
int ll16test(int, char **);
|
int ll16test(int, char **);
|
||||||
#endif
|
#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_ */
|
#endif /* _TEST_H_ */
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <vfs.h> // for vfs_sync()
|
#include <vfs.h> // for vfs_sync()
|
||||||
#include <lamebus/ltrace.h> // for ltrace_stop()
|
#include <lamebus/ltrace.h> // for ltrace_stop()
|
||||||
#include <kern/secret.h>
|
#include <kern/secret.h>
|
||||||
|
#include <test.h>
|
||||||
|
|
||||||
|
|
||||||
/* Flags word for DEBUG() macro. */
|
/* Flags word for DEBUG() macro. */
|
||||||
@ -93,9 +94,10 @@ console_send(void *junk, const char *data, size_t len)
|
|||||||
/*
|
/*
|
||||||
* kprintf and tprintf helper function.
|
* kprintf and tprintf helper function.
|
||||||
*/
|
*/
|
||||||
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
vkprintf(const char *fmt, va_list ap)
|
__kprintf(const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int chars;
|
int chars;
|
||||||
bool dolock;
|
bool dolock;
|
||||||
@ -134,7 +136,7 @@ kprintf(const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
chars = vkprintf(fmt, ap);
|
chars = __kprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return chars;
|
return chars;
|
||||||
@ -154,7 +156,7 @@ tkprintf(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
chars = vkprintf(fmt, ap);
|
chars = __kprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return chars;
|
return chars;
|
||||||
@ -173,7 +175,7 @@ nkprintf(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
chars = vkprintf(fmt, ap);
|
chars = __kprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return chars;
|
return chars;
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <kern/errmsg.h>
|
#include <kern/errmsg.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <thread.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like strdup, but calls kmalloc.
|
* Like strdup, but calls kmalloc.
|
||||||
@ -61,27 +60,3 @@ strerror(int errcode)
|
|||||||
panic("Invalid error code %d\n", errcode);
|
panic("Invalid error code %d\n", errcode);
|
||||||
return NULL;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
27
kern/test/lib.c
Normal file
27
kern/test/lib.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <types.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <test.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
@ -68,7 +68,6 @@
|
|||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <synch.h>
|
#include <synch.h>
|
||||||
#include <synchprobs.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by the driver during initialization.
|
* Called by the driver during initialization.
|
@ -11,7 +11,6 @@
|
|||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <current.h>
|
#include <current.h>
|
||||||
#include <synch.h>
|
#include <synch.h>
|
||||||
#include <synchprobs.h>
|
|
||||||
|
|
||||||
#define PROBLEMS_MAX_YIELDER 16
|
#define PROBLEMS_MAX_YIELDER 16
|
||||||
#define PROBLEMS_MAX_SPINNER 8192
|
#define PROBLEMS_MAX_SPINNER 8192
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <synch.h>
|
#include <synch.h>
|
||||||
#include <synchprobs.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by the driver during initialization.
|
* Called by the driver during initialization.
|
@ -47,18 +47,18 @@
|
|||||||
struct semaphore *
|
struct semaphore *
|
||||||
sem_create(const char *name, unsigned initial_count)
|
sem_create(const char *name, unsigned initial_count)
|
||||||
{
|
{
|
||||||
struct semaphore *sem;
|
struct semaphore *sem;
|
||||||
|
|
||||||
sem = kmalloc(sizeof(*sem));
|
sem = kmalloc(sizeof(*sem));
|
||||||
if (sem == NULL) {
|
if (sem == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem->sem_name = kstrdup(name);
|
sem->sem_name = kstrdup(name);
|
||||||
if (sem->sem_name == NULL) {
|
if (sem->sem_name == NULL) {
|
||||||
kfree(sem);
|
kfree(sem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem->sem_wchan = wchan_create(sem->sem_name);
|
sem->sem_wchan = wchan_create(sem->sem_name);
|
||||||
if (sem->sem_wchan == NULL) {
|
if (sem->sem_wchan == NULL) {
|
||||||
@ -68,39 +68,39 @@ sem_create(const char *name, unsigned initial_count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinlock_init(&sem->sem_lock);
|
spinlock_init(&sem->sem_lock);
|
||||||
sem->sem_count = initial_count;
|
sem->sem_count = initial_count;
|
||||||
|
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sem_destroy(struct semaphore *sem)
|
sem_destroy(struct semaphore *sem)
|
||||||
{
|
{
|
||||||
KASSERT(sem != NULL);
|
KASSERT(sem != NULL);
|
||||||
|
|
||||||
/* wchan_cleanup will assert if anyone's waiting on it */
|
/* wchan_cleanup will assert if anyone's waiting on it */
|
||||||
spinlock_cleanup(&sem->sem_lock);
|
spinlock_cleanup(&sem->sem_lock);
|
||||||
wchan_destroy(sem->sem_wchan);
|
wchan_destroy(sem->sem_wchan);
|
||||||
kfree(sem->sem_name);
|
kfree(sem->sem_name);
|
||||||
kfree(sem);
|
kfree(sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
P(struct semaphore *sem)
|
P(struct semaphore *sem)
|
||||||
{
|
{
|
||||||
KASSERT(sem != NULL);
|
KASSERT(sem != NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* May not block in an interrupt handler.
|
* May not block in an interrupt handler.
|
||||||
*
|
*
|
||||||
* For robustness, always check, even if we can actually
|
* For robustness, always check, even if we can actually
|
||||||
* complete the P without blocking.
|
* complete the P without blocking.
|
||||||
*/
|
*/
|
||||||
KASSERT(curthread->t_in_interrupt == false);
|
KASSERT(curthread->t_in_interrupt == false);
|
||||||
|
|
||||||
/* Use the semaphore spinlock to protect the wchan as well. */
|
/* Use the semaphore spinlock to protect the wchan as well. */
|
||||||
spinlock_acquire(&sem->sem_lock);
|
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
|
* Note that we don't maintain strict FIFO ordering of
|
||||||
@ -114,21 +114,21 @@ P(struct semaphore *sem)
|
|||||||
* ordering?
|
* ordering?
|
||||||
*/
|
*/
|
||||||
wchan_sleep(sem->sem_wchan, &sem->sem_lock);
|
wchan_sleep(sem->sem_wchan, &sem->sem_lock);
|
||||||
}
|
}
|
||||||
KASSERT(sem->sem_count > 0);
|
KASSERT(sem->sem_count > 0);
|
||||||
sem->sem_count--;
|
sem->sem_count--;
|
||||||
spinlock_release(&sem->sem_lock);
|
spinlock_release(&sem->sem_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
V(struct semaphore *sem)
|
V(struct semaphore *sem)
|
||||||
{
|
{
|
||||||
KASSERT(sem != NULL);
|
KASSERT(sem != NULL);
|
||||||
|
|
||||||
spinlock_acquire(&sem->sem_lock);
|
spinlock_acquire(&sem->sem_lock);
|
||||||
|
|
||||||
sem->sem_count++;
|
sem->sem_count++;
|
||||||
KASSERT(sem->sem_count > 0);
|
KASSERT(sem->sem_count > 0);
|
||||||
wchan_wakeone(sem->sem_wchan, &sem->sem_lock);
|
wchan_wakeone(sem->sem_wchan, &sem->sem_lock);
|
||||||
|
|
||||||
spinlock_release(&sem->sem_lock);
|
spinlock_release(&sem->sem_lock);
|
||||||
@ -141,59 +141,59 @@ V(struct semaphore *sem)
|
|||||||
struct lock *
|
struct lock *
|
||||||
lock_create(const char *name)
|
lock_create(const char *name)
|
||||||
{
|
{
|
||||||
struct lock *lock;
|
struct lock *lock;
|
||||||
|
|
||||||
lock = kmalloc(sizeof(*lock));
|
lock = kmalloc(sizeof(*lock));
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->lk_name = kstrdup(name);
|
lock->lk_name = kstrdup(name);
|
||||||
if (lock->lk_name == NULL) {
|
if (lock->lk_name == NULL) {
|
||||||
kfree(lock);
|
kfree(lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add stuff here as needed
|
// add stuff here as needed
|
||||||
|
|
||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lock_destroy(struct lock *lock)
|
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->lk_name);
|
||||||
kfree(lock);
|
kfree(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lock_acquire(struct lock *lock)
|
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
|
void
|
||||||
lock_release(struct lock *lock)
|
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
|
bool
|
||||||
lock_do_i_hold(struct lock *lock)
|
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 *
|
struct cv *
|
||||||
cv_create(const char *name)
|
cv_create(const char *name)
|
||||||
{
|
{
|
||||||
struct cv *cv;
|
struct cv *cv;
|
||||||
|
|
||||||
cv = kmalloc(sizeof(*cv));
|
cv = kmalloc(sizeof(*cv));
|
||||||
if (cv == NULL) {
|
if (cv == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv->cv_name = kstrdup(name);
|
cv->cv_name = kstrdup(name);
|
||||||
if (cv->cv_name==NULL) {
|
if (cv->cv_name==NULL) {
|
||||||
kfree(cv);
|
kfree(cv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add stuff here as needed
|
// add stuff here as needed
|
||||||
|
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cv_destroy(struct cv *cv)
|
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->cv_name);
|
||||||
kfree(cv);
|
kfree(cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cv_wait(struct cv *cv, struct lock *lock)
|
cv_wait(struct cv *cv, struct lock *lock)
|
||||||
{
|
{
|
||||||
// Write this
|
// Write this
|
||||||
(void)cv; // suppress warning until code gets written
|
(void)cv; // suppress warning until code gets written
|
||||||
(void)lock; // suppress warning until code gets written
|
(void)lock; // suppress warning until code gets written
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cv_signal(struct cv *cv, struct lock *lock)
|
cv_signal(struct cv *cv, struct lock *lock)
|
||||||
{
|
{
|
||||||
// Write this
|
// Write this
|
||||||
(void)cv; // suppress warning until code gets written
|
(void)cv; // suppress warning until code gets written
|
||||||
(void)lock; // suppress warning until code gets written
|
(void)lock; // suppress warning until code gets written
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user