fix: format + dont track build folders
This commit is contained in:
parent
b77ad042ca
commit
c173f2b9b8
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
kern/compile/
|
||||
build/
|
||||
build/*
|
||||
**/build
|
||||
|
@ -74,8 +74,8 @@ int splx(int);
|
||||
/*
|
||||
* Integer interrupt priority levels.
|
||||
*/
|
||||
#define IPL_NONE 0
|
||||
#define IPL_HIGH 1
|
||||
#define IPL_NONE 0
|
||||
#define IPL_HIGH 1
|
||||
|
||||
/*
|
||||
* Lower-level functions for explicitly raising and lowering
|
||||
@ -92,18 +92,9 @@ void spllower(int oldipl, int newipl);
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
SPL_INLINE
|
||||
int
|
||||
spl0(void)
|
||||
{
|
||||
return splx(IPL_NONE);
|
||||
}
|
||||
int spl0(void) { return splx(IPL_NONE); }
|
||||
|
||||
SPL_INLINE
|
||||
int
|
||||
splhigh(void)
|
||||
{
|
||||
return splx(IPL_HIGH);
|
||||
}
|
||||
|
||||
int splhigh(void) { return splx(IPL_HIGH); }
|
||||
|
||||
#endif /* _SPL_H_ */
|
||||
|
@ -34,7 +34,6 @@
|
||||
* Header file for synchronization primitives.
|
||||
*/
|
||||
|
||||
|
||||
#include <spinlock.h>
|
||||
|
||||
/*
|
||||
@ -44,10 +43,10 @@
|
||||
* internally.
|
||||
*/
|
||||
struct semaphore {
|
||||
char *sem_name;
|
||||
struct wchan *sem_wchan;
|
||||
struct spinlock sem_lock;
|
||||
volatile unsigned sem_count;
|
||||
char *sem_name;
|
||||
struct wchan *sem_wchan;
|
||||
struct spinlock sem_lock;
|
||||
volatile unsigned sem_count;
|
||||
};
|
||||
|
||||
struct semaphore *sem_create(const char *name, unsigned initial_count);
|
||||
@ -62,7 +61,6 @@ void sem_destroy(struct semaphore *);
|
||||
void P(struct semaphore *);
|
||||
void V(struct semaphore *);
|
||||
|
||||
|
||||
/*
|
||||
* Simple lock for mutual exclusion.
|
||||
*
|
||||
@ -73,10 +71,10 @@ void V(struct semaphore *);
|
||||
* (should be) made internally.
|
||||
*/
|
||||
struct lock {
|
||||
char *lk_name;
|
||||
HANGMAN_LOCKABLE(lk_hangman); /* Deadlock detector hook. */
|
||||
// add what you need here
|
||||
// (don't forget to mark things volatile as needed)
|
||||
char *lk_name;
|
||||
HANGMAN_LOCKABLE(lk_hangman); /* Deadlock detector hook. */
|
||||
// add what you need here
|
||||
// (don't forget to mark things volatile as needed)
|
||||
};
|
||||
|
||||
struct lock *lock_create(const char *name);
|
||||
@ -97,7 +95,6 @@ void lock_acquire(struct lock *);
|
||||
void lock_release(struct lock *);
|
||||
bool lock_do_i_hold(struct lock *);
|
||||
|
||||
|
||||
/*
|
||||
* Condition variable.
|
||||
*
|
||||
@ -113,9 +110,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);
|
||||
@ -138,5 +135,4 @@ void cv_wait(struct cv *cv, struct lock *lock);
|
||||
void cv_signal(struct cv *cv, struct lock *lock);
|
||||
void cv_broadcast(struct cv *cv, struct lock *lock);
|
||||
|
||||
|
||||
#endif /* _SYNCH_H_ */
|
||||
|
@ -37,10 +37,9 @@
|
||||
#include <current.h>
|
||||
#include <synch.h>
|
||||
#include <mainbus.h>
|
||||
#include <vfs.h> // for vfs_sync()
|
||||
#include <vfs.h> // for vfs_sync()
|
||||
#include <lamebus/ltrace.h> // for ltrace_stop()
|
||||
|
||||
|
||||
/* Flags word for DEBUG() macro. */
|
||||
uint32_t dbflags = 0;
|
||||
|
||||
@ -50,79 +49,66 @@ static struct lock *kprintf_lock;
|
||||
/* Lock for polled kprintfs */
|
||||
static struct spinlock kprintf_spinlock;
|
||||
|
||||
|
||||
/*
|
||||
* Warning: all this has to work from interrupt handlers and when
|
||||
* interrupts are disabled.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Create the kprintf lock. Must be called before creating a second
|
||||
* thread or enabling a second CPU.
|
||||
*/
|
||||
void
|
||||
kprintf_bootstrap(void)
|
||||
{
|
||||
KASSERT(kprintf_lock == NULL);
|
||||
void kprintf_bootstrap(void) {
|
||||
KASSERT(kprintf_lock == NULL);
|
||||
|
||||
kprintf_lock = lock_create("kprintf_lock");
|
||||
if (kprintf_lock == NULL) {
|
||||
panic("Could not create kprintf_lock\n");
|
||||
}
|
||||
spinlock_init(&kprintf_spinlock);
|
||||
kprintf_lock = lock_create("kprintf_lock");
|
||||
if (kprintf_lock == NULL) {
|
||||
panic("Could not create kprintf_lock\n");
|
||||
}
|
||||
spinlock_init(&kprintf_spinlock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send characters to the console. Backend for __printf.
|
||||
*/
|
||||
static
|
||||
void
|
||||
console_send(void *junk, const char *data, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
static void console_send(void *junk, const char *data, size_t len) {
|
||||
size_t i;
|
||||
|
||||
(void)junk;
|
||||
(void)junk;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
putch(data[i]);
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
putch(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Printf to the console.
|
||||
*/
|
||||
int
|
||||
kprintf(const char *fmt, ...)
|
||||
{
|
||||
int chars;
|
||||
va_list ap;
|
||||
bool dolock;
|
||||
int kprintf(const char *fmt, ...) {
|
||||
int chars;
|
||||
va_list ap;
|
||||
bool dolock;
|
||||
|
||||
dolock = kprintf_lock != NULL
|
||||
&& curthread->t_in_interrupt == false
|
||||
&& curthread->t_curspl == 0
|
||||
&& curcpu->c_spinlocks == 0;
|
||||
dolock = kprintf_lock != NULL && curthread->t_in_interrupt == false &&
|
||||
curthread->t_curspl == 0 && curcpu->c_spinlocks == 0;
|
||||
|
||||
if (dolock) {
|
||||
lock_acquire(kprintf_lock);
|
||||
}
|
||||
else {
|
||||
spinlock_acquire(&kprintf_spinlock);
|
||||
}
|
||||
if (dolock) {
|
||||
lock_acquire(kprintf_lock);
|
||||
} else {
|
||||
spinlock_acquire(&kprintf_spinlock);
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
chars = __vprintf(console_send, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
chars = __vprintf(console_send, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (dolock) {
|
||||
lock_release(kprintf_lock);
|
||||
}
|
||||
else {
|
||||
spinlock_release(&kprintf_spinlock);
|
||||
}
|
||||
if (dolock) {
|
||||
lock_release(kprintf_lock);
|
||||
} else {
|
||||
spinlock_release(&kprintf_spinlock);
|
||||
}
|
||||
|
||||
return chars;
|
||||
return chars;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -130,87 +116,83 @@ kprintf(const char *fmt, ...)
|
||||
* passed and then halts the system.
|
||||
*/
|
||||
|
||||
void
|
||||
panic(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void panic(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
/*
|
||||
* When we reach panic, the system is usually fairly screwed up.
|
||||
* It's not entirely uncommon for anything else we try to do
|
||||
* here to trigger more panics.
|
||||
*
|
||||
* This variable makes sure that if we try to do something here,
|
||||
* and it causes another panic, *that* panic doesn't try again;
|
||||
* trying again almost inevitably causes infinite recursion.
|
||||
*
|
||||
* This is not excessively paranoid - these things DO happen!
|
||||
*/
|
||||
static volatile int evil;
|
||||
/*
|
||||
* When we reach panic, the system is usually fairly screwed up.
|
||||
* It's not entirely uncommon for anything else we try to do
|
||||
* here to trigger more panics.
|
||||
*
|
||||
* This variable makes sure that if we try to do something here,
|
||||
* and it causes another panic, *that* panic doesn't try again;
|
||||
* trying again almost inevitably causes infinite recursion.
|
||||
*
|
||||
* This is not excessively paranoid - these things DO happen!
|
||||
*/
|
||||
static volatile int evil;
|
||||
|
||||
if (evil == 0) {
|
||||
evil = 1;
|
||||
if (evil == 0) {
|
||||
evil = 1;
|
||||
|
||||
/*
|
||||
* Not only do we not want to be interrupted while
|
||||
* panicking, but we also want the console to be
|
||||
* printing in polling mode so as not to do context
|
||||
* switches. So turn interrupts off on this CPU.
|
||||
*/
|
||||
splhigh();
|
||||
}
|
||||
/*
|
||||
* Not only do we not want to be interrupted while
|
||||
* panicking, but we also want the console to be
|
||||
* printing in polling mode so as not to do context
|
||||
* switches. So turn interrupts off on this CPU.
|
||||
*/
|
||||
splhigh();
|
||||
}
|
||||
|
||||
if (evil == 1) {
|
||||
evil = 2;
|
||||
if (evil == 1) {
|
||||
evil = 2;
|
||||
|
||||
/* Kill off other threads and halt other CPUs. */
|
||||
thread_panic();
|
||||
}
|
||||
/* Kill off other threads and halt other CPUs. */
|
||||
thread_panic();
|
||||
}
|
||||
|
||||
if (evil == 2) {
|
||||
evil = 3;
|
||||
if (evil == 2) {
|
||||
evil = 3;
|
||||
|
||||
/* Print the message. */
|
||||
kprintf("panic: ");
|
||||
va_start(ap, fmt);
|
||||
__vprintf(console_send, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
/* Print the message. */
|
||||
kprintf("panic: ");
|
||||
va_start(ap, fmt);
|
||||
__vprintf(console_send, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
if (evil == 3) {
|
||||
evil = 4;
|
||||
if (evil == 3) {
|
||||
evil = 4;
|
||||
|
||||
/* Drop to the debugger. */
|
||||
ltrace_stop(0);
|
||||
}
|
||||
/* Drop to the debugger. */
|
||||
ltrace_stop(0);
|
||||
}
|
||||
|
||||
if (evil == 4) {
|
||||
evil = 5;
|
||||
if (evil == 4) {
|
||||
evil = 5;
|
||||
|
||||
/* Try to sync the disks. */
|
||||
vfs_sync();
|
||||
}
|
||||
/* Try to sync the disks. */
|
||||
vfs_sync();
|
||||
}
|
||||
|
||||
if (evil == 5) {
|
||||
evil = 6;
|
||||
if (evil == 5) {
|
||||
evil = 6;
|
||||
|
||||
/* Shut down or reboot the system. */
|
||||
mainbus_panic();
|
||||
}
|
||||
/* Shut down or reboot the system. */
|
||||
mainbus_panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Last resort, just in case.
|
||||
*/
|
||||
/*
|
||||
* Last resort, just in case.
|
||||
*/
|
||||
|
||||
for (;;);
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assertion failures go through this.
|
||||
*/
|
||||
void
|
||||
badassert(const char *expr, const char *file, int line, const char *func)
|
||||
{
|
||||
panic("Assertion failed: %s, at %s:%d (%s)\n",
|
||||
expr, file, line, func);
|
||||
void badassert(const char *expr, const char *file, int line, const char *func) {
|
||||
panic("Assertion failed: %s, at %s:%d (%s)\n", expr, file, line, func);
|
||||
}
|
||||
|
192
kern/main/main.c
192
kern/main/main.c
@ -49,8 +49,7 @@
|
||||
#include <syscall.h>
|
||||
#include <test.h>
|
||||
#include <version.h>
|
||||
#include "autoconf.h" // for pseudoconfig
|
||||
|
||||
#include "autoconf.h" // for pseudoconfig
|
||||
|
||||
/*
|
||||
* These two pieces of data are maintained by the makefiles and build system.
|
||||
@ -71,92 +70,85 @@ static const char harvard_copyright[] =
|
||||
"Copyright (c) 2000, 2001-2005, 2008-2011, 2013, 2014\n"
|
||||
" President and Fellows of Harvard College. All rights reserved.\n";
|
||||
|
||||
|
||||
/*
|
||||
* Initial boot sequence.
|
||||
*/
|
||||
static
|
||||
void
|
||||
boot(void)
|
||||
{
|
||||
/*
|
||||
* The order of these is important!
|
||||
* Don't go changing it without thinking about the consequences.
|
||||
*
|
||||
* Among other things, be aware that console output gets
|
||||
* buffered up at first and does not actually appear until
|
||||
* mainbus_bootstrap() attaches the console device. This can
|
||||
* be remarkably confusing if a bug occurs at this point. So
|
||||
* don't put new code before mainbus_bootstrap if you don't
|
||||
* absolutely have to.
|
||||
*
|
||||
* Also note that the buffer for this is only 1k. If you
|
||||
* overflow it, the system will crash without printing
|
||||
* anything at all. You can make it larger though (it's in
|
||||
* dev/generic/console.c).
|
||||
*/
|
||||
static void boot(void) {
|
||||
/*
|
||||
* The order of these is important!
|
||||
* Don't go changing it without thinking about the consequences.
|
||||
*
|
||||
* Among other things, be aware that console output gets
|
||||
* buffered up at first and does not actually appear until
|
||||
* mainbus_bootstrap() attaches the console device. This can
|
||||
* be remarkably confusing if a bug occurs at this point. So
|
||||
* don't put new code before mainbus_bootstrap if you don't
|
||||
* absolutely have to.
|
||||
*
|
||||
* Also note that the buffer for this is only 1k. If you
|
||||
* overflow it, the system will crash without printing
|
||||
* anything at all. You can make it larger though (it's in
|
||||
* dev/generic/console.c).
|
||||
*/
|
||||
|
||||
kprintf("\n");
|
||||
kprintf("OS/161 base system version %s\n", BASE_VERSION);
|
||||
kprintf("%s", harvard_copyright);
|
||||
kprintf("\n");
|
||||
kprintf("\n");
|
||||
kprintf("OS/161 base system version %s\n", BASE_VERSION);
|
||||
kprintf("%s", harvard_copyright);
|
||||
kprintf("\n");
|
||||
|
||||
kprintf("Put-your-group-name-here's system version %s (%s #%d)\n",
|
||||
GROUP_VERSION, buildconfig, buildversion);
|
||||
kprintf("\n");
|
||||
kprintf("Minh Tran's system version %s (%s #%d)\n", GROUP_VERSION,
|
||||
buildconfig, buildversion);
|
||||
kprintf("\n");
|
||||
|
||||
/* Early initialization. */
|
||||
ram_bootstrap();
|
||||
proc_bootstrap();
|
||||
thread_bootstrap();
|
||||
hardclock_bootstrap();
|
||||
vfs_bootstrap();
|
||||
kheap_nextgeneration();
|
||||
/* Early initialization. */
|
||||
ram_bootstrap();
|
||||
proc_bootstrap();
|
||||
thread_bootstrap();
|
||||
hardclock_bootstrap();
|
||||
vfs_bootstrap();
|
||||
kheap_nextgeneration();
|
||||
|
||||
/* Probe and initialize devices. Interrupts should come on. */
|
||||
kprintf("Device probe...\n");
|
||||
KASSERT(curthread->t_curspl > 0);
|
||||
mainbus_bootstrap();
|
||||
KASSERT(curthread->t_curspl == 0);
|
||||
/* Now do pseudo-devices. */
|
||||
pseudoconfig();
|
||||
kprintf("\n");
|
||||
kheap_nextgeneration();
|
||||
/* Probe and initialize devices. Interrupts should come on. */
|
||||
kprintf("Device probe...\n");
|
||||
KASSERT(curthread->t_curspl > 0);
|
||||
mainbus_bootstrap();
|
||||
KASSERT(curthread->t_curspl == 0);
|
||||
/* Now do pseudo-devices. */
|
||||
pseudoconfig();
|
||||
kprintf("\n");
|
||||
kheap_nextgeneration();
|
||||
|
||||
/* Late phase of initialization. */
|
||||
vm_bootstrap();
|
||||
kprintf_bootstrap();
|
||||
thread_start_cpus();
|
||||
/* Late phase of initialization. */
|
||||
vm_bootstrap();
|
||||
kprintf_bootstrap();
|
||||
thread_start_cpus();
|
||||
|
||||
/* Default bootfs - but ignore failure, in case emu0 doesn't exist */
|
||||
vfs_setbootfs("emu0");
|
||||
/* Default bootfs - but ignore failure, in case emu0 doesn't exist */
|
||||
vfs_setbootfs("emu0");
|
||||
|
||||
kheap_nextgeneration();
|
||||
kheap_nextgeneration();
|
||||
|
||||
/*
|
||||
* Make sure various things aren't screwed up.
|
||||
*/
|
||||
COMPILE_ASSERT(sizeof(userptr_t) == sizeof(char *));
|
||||
COMPILE_ASSERT(sizeof(*(userptr_t)0) == sizeof(char));
|
||||
/*
|
||||
* Make sure various things aren't screwed up.
|
||||
*/
|
||||
COMPILE_ASSERT(sizeof(userptr_t) == sizeof(char *));
|
||||
COMPILE_ASSERT(sizeof(*(userptr_t)0) == sizeof(char));
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown sequence. Opposite to boot().
|
||||
*/
|
||||
static
|
||||
void
|
||||
shutdown(void)
|
||||
{
|
||||
static void shutdown(void) {
|
||||
|
||||
kprintf("Shutting down.\n");
|
||||
kprintf("Shutting down.\n");
|
||||
|
||||
vfs_clearbootfs();
|
||||
vfs_clearcurdir();
|
||||
vfs_unmountall();
|
||||
vfs_clearbootfs();
|
||||
vfs_clearcurdir();
|
||||
vfs_unmountall();
|
||||
|
||||
thread_shutdown();
|
||||
thread_shutdown();
|
||||
|
||||
splhigh();
|
||||
splhigh();
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
@ -168,49 +160,45 @@ shutdown(void)
|
||||
* not because this is where system call code should go. Other syscall
|
||||
* code should probably live in the "syscall" directory.
|
||||
*/
|
||||
int
|
||||
sys_reboot(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case RB_REBOOT:
|
||||
case RB_HALT:
|
||||
case RB_POWEROFF:
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
int sys_reboot(int code) {
|
||||
switch (code) {
|
||||
case RB_REBOOT:
|
||||
case RB_HALT:
|
||||
case RB_POWEROFF:
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
shutdown();
|
||||
shutdown();
|
||||
|
||||
switch (code) {
|
||||
case RB_HALT:
|
||||
kprintf("The system is halted.\n");
|
||||
mainbus_halt();
|
||||
break;
|
||||
case RB_REBOOT:
|
||||
kprintf("Rebooting...\n");
|
||||
mainbus_reboot();
|
||||
break;
|
||||
case RB_POWEROFF:
|
||||
kprintf("The system is halted.\n");
|
||||
mainbus_poweroff();
|
||||
break;
|
||||
}
|
||||
switch (code) {
|
||||
case RB_HALT:
|
||||
kprintf("The system is halted.\n");
|
||||
mainbus_halt();
|
||||
break;
|
||||
case RB_REBOOT:
|
||||
kprintf("Rebooting...\n");
|
||||
mainbus_reboot();
|
||||
break;
|
||||
case RB_POWEROFF:
|
||||
kprintf("The system is halted.\n");
|
||||
mainbus_poweroff();
|
||||
break;
|
||||
}
|
||||
|
||||
panic("reboot operation failed\n");
|
||||
return 0;
|
||||
panic("reboot operation failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kernel main. Boot up, then fork the menu thread; wait for a reboot
|
||||
* request, and then shut down.
|
||||
*/
|
||||
void
|
||||
kmain(char *arguments)
|
||||
{
|
||||
boot();
|
||||
void kmain(char *arguments) {
|
||||
boot();
|
||||
|
||||
menu(arguments);
|
||||
menu(arguments);
|
||||
|
||||
/* Should not get here */
|
||||
/* Should not get here */
|
||||
}
|
||||
|
@ -44,226 +44,197 @@
|
||||
//
|
||||
// Semaphore.
|
||||
|
||||
struct semaphore *
|
||||
sem_create(const char *name, unsigned initial_count)
|
||||
{
|
||||
struct semaphore *sem;
|
||||
struct semaphore *sem_create(const char *name, unsigned initial_count) {
|
||||
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) {
|
||||
kfree(sem->sem_name);
|
||||
kfree(sem);
|
||||
return NULL;
|
||||
}
|
||||
sem->sem_wchan = wchan_create(sem->sem_name);
|
||||
if (sem->sem_wchan == NULL) {
|
||||
kfree(sem->sem_name);
|
||||
kfree(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spinlock_init(&sem->sem_lock);
|
||||
sem->sem_count = initial_count;
|
||||
spinlock_init(&sem->sem_lock);
|
||||
sem->sem_count = initial_count;
|
||||
|
||||
return sem;
|
||||
return sem;
|
||||
}
|
||||
|
||||
void
|
||||
sem_destroy(struct semaphore *sem)
|
||||
{
|
||||
KASSERT(sem != NULL);
|
||||
void sem_destroy(struct semaphore *sem) {
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void
|
||||
P(struct semaphore *sem)
|
||||
{
|
||||
KASSERT(sem != NULL);
|
||||
void P(struct semaphore *sem) {
|
||||
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) {
|
||||
/*
|
||||
*
|
||||
* Note that we don't maintain strict FIFO ordering of
|
||||
* threads going through the semaphore; that is, we
|
||||
* might "get" it on the first try even if other
|
||||
* threads are waiting. Apparently according to some
|
||||
* textbooks semaphores must for some reason have
|
||||
* strict ordering. Too bad. :-)
|
||||
*
|
||||
* Exercise: how would you implement strict FIFO
|
||||
* ordering?
|
||||
*/
|
||||
wchan_sleep(sem->sem_wchan, &sem->sem_lock);
|
||||
}
|
||||
KASSERT(sem->sem_count > 0);
|
||||
sem->sem_count--;
|
||||
spinlock_release(&sem->sem_lock);
|
||||
/* Use the semaphore spinlock to protect the wchan as well. */
|
||||
spinlock_acquire(&sem->sem_lock);
|
||||
while (sem->sem_count == 0) {
|
||||
/*
|
||||
*
|
||||
* Note that we don't maintain strict FIFO ordering of
|
||||
* threads going through the semaphore; that is, we
|
||||
* might "get" it on the first try even if other
|
||||
* threads are waiting. Apparently according to some
|
||||
* textbooks semaphores must for some reason have
|
||||
* strict ordering. Too bad. :-)
|
||||
*
|
||||
* Exercise: how would you implement strict FIFO
|
||||
* ordering?
|
||||
*/
|
||||
wchan_sleep(sem->sem_wchan, &sem->sem_lock);
|
||||
}
|
||||
KASSERT(sem->sem_count > 0);
|
||||
sem->sem_count--;
|
||||
spinlock_release(&sem->sem_lock);
|
||||
}
|
||||
|
||||
void
|
||||
V(struct semaphore *sem)
|
||||
{
|
||||
KASSERT(sem != NULL);
|
||||
void V(struct semaphore *sem) {
|
||||
KASSERT(sem != NULL);
|
||||
|
||||
spinlock_acquire(&sem->sem_lock);
|
||||
spinlock_acquire(&sem->sem_lock);
|
||||
|
||||
sem->sem_count++;
|
||||
KASSERT(sem->sem_count > 0);
|
||||
wchan_wakeone(sem->sem_wchan, &sem->sem_lock);
|
||||
sem->sem_count++;
|
||||
KASSERT(sem->sem_count > 0);
|
||||
wchan_wakeone(sem->sem_wchan, &sem->sem_lock);
|
||||
|
||||
spinlock_release(&sem->sem_lock);
|
||||
spinlock_release(&sem->sem_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Lock.
|
||||
|
||||
struct lock *
|
||||
lock_create(const char *name)
|
||||
{
|
||||
struct lock *lock;
|
||||
struct lock *lock_create(const char *name) {
|
||||
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;
|
||||
}
|
||||
|
||||
HANGMAN_LOCKABLEINIT(&lock->lk_hangman, lock->lk_name);
|
||||
HANGMAN_LOCKABLEINIT(&lock->lk_hangman, lock->lk_name);
|
||||
|
||||
// add stuff here as needed
|
||||
// add stuff here as needed
|
||||
|
||||
return lock;
|
||||
return lock;
|
||||
}
|
||||
|
||||
void
|
||||
lock_destroy(struct lock *lock)
|
||||
{
|
||||
KASSERT(lock != NULL);
|
||||
void lock_destroy(struct lock *lock) {
|
||||
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)
|
||||
{
|
||||
/* Call this (atomically) before waiting for a lock */
|
||||
//HANGMAN_WAIT(&curthread->t_hangman, &lock->lk_hangman);
|
||||
void lock_acquire(struct lock *lock) {
|
||||
/* Call this (atomically) before waiting for a lock */
|
||||
// HANGMAN_WAIT(&curthread->t_hangman, &lock->lk_hangman);
|
||||
|
||||
// Write this
|
||||
// Write this
|
||||
|
||||
(void)lock; // suppress warning until code gets written
|
||||
(void)lock; // suppress warning until code gets written
|
||||
|
||||
/* Call this (atomically) once the lock is acquired */
|
||||
//HANGMAN_ACQUIRE(&curthread->t_hangman, &lock->lk_hangman);
|
||||
/* Call this (atomically) once the lock is acquired */
|
||||
// HANGMAN_ACQUIRE(&curthread->t_hangman, &lock->lk_hangman);
|
||||
}
|
||||
|
||||
void
|
||||
lock_release(struct lock *lock)
|
||||
{
|
||||
/* Call this (atomically) when the lock is released */
|
||||
//HANGMAN_RELEASE(&curthread->t_hangman, &lock->lk_hangman);
|
||||
void lock_release(struct lock *lock) {
|
||||
/* Call this (atomically) when the lock is released */
|
||||
// HANGMAN_RELEASE(&curthread->t_hangman, &lock->lk_hangman);
|
||||
|
||||
// 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
|
||||
bool lock_do_i_hold(struct lock *lock) {
|
||||
// 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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CV
|
||||
|
||||
struct cv *cv_create(const char *name) {
|
||||
struct cv *cv;
|
||||
|
||||
struct cv *
|
||||
cv_create(const char *name)
|
||||
{
|
||||
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);
|
||||
void cv_destroy(struct cv *cv) {
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
void
|
||||
cv_signal(struct cv *cv, struct lock *lock)
|
||||
{
|
||||
// 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
|
||||
(void)cv; // suppress warning until code gets written
|
||||
(void)lock; // suppress warning until code gets written
|
||||
}
|
||||
|
||||
void
|
||||
cv_broadcast(struct cv *cv, struct lock *lock)
|
||||
{
|
||||
// Write this
|
||||
(void)cv; // suppress warning until code gets written
|
||||
(void)lock; // suppress warning until code gets written
|
||||
void cv_broadcast(struct cv *cv, struct lock *lock) {
|
||||
// Write this
|
||||
(void)cv; // suppress warning until code gets written
|
||||
(void)lock; // suppress warning until code gets written
|
||||
}
|
||||
|
1493
kern/thread/thread.c
1493
kern/thread/thread.c
File diff suppressed because it is too large
Load Diff
1293
kern/vm/kmalloc.c
1293
kern/vm/kmalloc.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user