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