From: Ben Pfaff Date: Wed, 18 Aug 2004 00:12:54 +0000 (+0000) Subject: Working backdoor filesystem implementation. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3fc16f6e9abc98a3bd5427eb210669860609a224;p=pintos-anon Working backdoor filesystem implementation. --- diff --git a/src/Makefile.inc b/src/Makefile.inc index a086db0..19b911c 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -8,10 +8,10 @@ VPATH := $(VPATH):$(TOP_SRCDIR)/filesys -include *.d -DEFINES = +DEFINES += -DCNACHOS86 WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes CFLAGS = -g -O3 -MMD $(WARNINGS) $(INCLUDES) $(DEFINES) -ASFLAGS = $(INCLUDES) $(DEFINES) +ASFLAGS = -Wa,--gstabs+ $(INCLUDES) $(DEFINES) # Core kernel. THREADS_SRC = start.S # Must be linked first. @@ -69,5 +69,3 @@ diskimage.bin: loader.bin kernel.bin clean: rm -f *.o *.d *.bin kernel.bin.data kernel.bin.pad intr-stubs.S - - diff --git a/src/filesys/build/Makefile b/src/filesys/build/Makefile index 281de9c..2c7ce69 100644 --- a/src/filesys/build/Makefile +++ b/src/filesys/build/Makefile @@ -1,5 +1,5 @@ TOP_SRCDIR = ../.. -DEFINES = -DFILESYS_STUB +DEFINES = -DFILESYS -DFILESYS_STUB SOURCES = $(THREADS_SRC) $(DEVICES_SRC) $(LIB_SRC) $(FILESYS_SRC) INCLUDES = -I$(TOP_SRCDIR)/threads -I$(TOP_SRCDIR)/devices \ -I$(TOP_SRCDIR)/lib -I$(TOP_SRCDIR)/filesys diff --git a/src/filesys/file.c b/src/filesys/file.c index b2a4942..0c18ab0 100644 --- a/src/filesys/file.c +++ b/src/filesys/file.c @@ -1,51 +1,98 @@ #include "file.h" #ifdef FILESYS_STUB +#include "debug.h" +#include "filesys-stub.h" +#include "lib.h" +#include "malloc.h" + +void +file_close (struct file *file) +{ + filesys_stub_lock (); + filesys_stub_put_string ("close"); + filesys_stub_put_file (file); + filesys_stub_match_string ("close"); + filesys_stub_unlock (); +} + off_t file_read (struct file *file, void *buffer, off_t size) { - int32_t retval = -1; - filesys_stub_send ("s'read' i i", (int32_t) file, (int32_t) size); - filesys_stub_receive ("s'read' i", &retval); + int32_t retval; + + filesys_stub_lock (); + filesys_stub_put_string ("read"); + filesys_stub_put_file (file); + filesys_stub_put_uint32 (size); + filesys_stub_match_string ("read"); + retval = filesys_stub_get_int32 (); if (retval > 0) { - if (!filesys_stub_receive ("B", buffer, (size_t) retval)) - retval = -1; + ASSERT (retval <= size); + filesys_stub_get_bytes (buffer, retval); } + filesys_stub_unlock (); + return retval; } off_t file_write (struct file *file, const void *buffer, off_t size) { - int32_t retval = -1; - filesys_stub_send ("s'write' i B", (int32_t) file, buffer, (size_t) size); - filesys_stub_receive ("s'write' i", &retval); + int32_t retval; + + filesys_stub_lock (); + filesys_stub_put_string ("write"); + filesys_stub_put_file (file); + filesys_stub_put_uint32 (size); + filesys_stub_put_bytes (buffer, size); + filesys_stub_match_string ("write"); + retval = filesys_stub_get_int32 (); + ASSERT (retval <= size); + filesys_stub_unlock (); + return retval; } off_t file_length (struct file *file) { - int32_t length = -1; - filesys_stub_send ("s'length' i", (int32_t) file); - filesys_stub_receive ("s'length' i", &length); + int32_t length; + + filesys_stub_lock (); + filesys_stub_put_string ("length"); + filesys_stub_put_file (file); + filesys_stub_match_string ("length"); + length = filesys_stub_get_int32 (); + filesys_stub_unlock (); + return length; } void file_seek (struct file *file, off_t pos) { - filesys_stub_send ("s'seek' i i", (int32_t) file, (int32_t) pos); - filesys_stub_receive ("s'seek'"); + filesys_stub_lock (); + filesys_stub_put_string ("seek"); + filesys_stub_put_file (file); + filesys_stub_put_uint32 (pos); + filesys_stub_match_string ("seek"); + filesys_stub_unlock (); } off_t file_tell (struct file *file) { - int32_t pos = -1; - filesys_stub_send ("s'tell' i", (int32_t) file); - filesys_stub_receive ("s'tell'", &pos); + int32_t pos; + + filesys_stub_lock (); + filesys_stub_put_string ("tell"); + filesys_stub_put_file (file); + filesys_stub_match_string ("tell"); + pos = filesys_stub_get_int32 (); + filesys_stub_unlock (); + return pos; } #endif /* FILESYS_STUB */ diff --git a/src/filesys/file.h b/src/filesys/file.h index 689aa6d..8f2fbc9 100644 --- a/src/filesys/file.h +++ b/src/filesys/file.h @@ -7,6 +7,7 @@ typedef int32_t off_t; struct file; +void file_close (struct file *); off_t file_read (struct file *, void *, off_t); off_t file_write (struct file *, const void *, off_t); off_t file_length (struct file *); diff --git a/src/filesys/filesys-stub.c b/src/filesys/filesys-stub.c index 23d133b..29c4cb9 100644 --- a/src/filesys/filesys-stub.c +++ b/src/filesys/filesys-stub.c @@ -3,36 +3,119 @@ #include "backdoor.h" #include "debug.h" #include "io.h" +#include "lib.h" +#include "synch.h" +static struct lock lock; + +void +filesys_stub_init (void) +{ + lock_init (&lock, "filesys-stub"); +} + +void +filesys_stub_lock (void) +{ + lock_acquire (&lock); +} + +void +filesys_stub_unlock (void) +{ + lock_release (&lock); +} + static void out_byte (uint8_t byte, void *aux UNUSED) { outb (0x8901, byte); } -void -filesys_stub_send (const char *types, ...) +void +filesys_stub_put_bool (bool b) +{ + backdoor_put_bool (b, out_byte, NULL); +} + +void +filesys_stub_put_bytes (const void *buffer, size_t cnt) +{ + backdoor_put_bytes (buffer, cnt, out_byte, NULL); +} + +void +filesys_stub_put_file (struct file *file) +{ + ASSERT (file != NULL); + filesys_stub_put_int32 ((int32_t) file - 1); +} + +void +filesys_stub_put_int32 (int32_t value) +{ + backdoor_put_int32 (value, out_byte, NULL); +} + +void +filesys_stub_put_string (const char *string) +{ + backdoor_put_string (string, out_byte, NULL); +} + +void +filesys_stub_put_uint32 (uint32_t value) { - va_list args; + backdoor_put_uint32 (value, out_byte, NULL); +} - va_start (args, types); - backdoor_vmarshal (types, args, out_byte, NULL); - va_end (args); +static uint8_t +in_byte (void *aux UNUSED) +{ + return inb (0x8901); } -static bool -in_byte (uint8_t *byte, void *aux UNUSED) +bool +filesys_stub_get_bool (void) { - *byte = inb (0x8901); - return true; + return backdoor_get_bool (in_byte, NULL); } -void -filesys_stub_receive (const char *types, ...) +void +filesys_stub_get_bytes (void *buffer, size_t size) { - va_list args; + backdoor_get_bytes (buffer, size, in_byte, NULL); +} - va_start (args, types); - backdoor_vunmarshal (types, args, in_byte, NULL); - va_end (args); +struct file * +filesys_stub_get_file (void) +{ + int32_t fd = filesys_stub_get_int32 (); + return fd < 0 ? NULL : (struct file *) (fd + 1); } + +int32_t +filesys_stub_get_int32 (void) +{ + return backdoor_get_int32 (in_byte, NULL); +} + +void +filesys_stub_match_string (const char *string) +{ + if (backdoor_get_uint32 (in_byte, NULL) != strlen (string)) + panic ("string match failed"); + while (*string != '\0') + { + uint8_t c = *string++; + if (c != in_byte (NULL)) + panic ("string match failed"); + } +} + +uint32_t +filesys_stub_get_uint32 (void) +{ + return backdoor_get_uint32 (in_byte, NULL); +} + diff --git a/src/filesys/filesys-stub.h b/src/filesys/filesys-stub.h index 1bc6c59..da0b22e 100644 --- a/src/filesys/filesys-stub.h +++ b/src/filesys/filesys-stub.h @@ -1,7 +1,28 @@ #ifndef HEADER_FILESYS_STUB_H #define HEADER_FILESYS_STUB_H 1 -void filesys_stub_send (const char *types, ...); -void filesys_stub_receive (const char *types, ...); +#include +#include +#include + +struct file; + +void filesys_stub_init (void); +void filesys_stub_lock (void); +void filesys_stub_unlock (void); + +void filesys_stub_put_bool (bool); +void filesys_stub_put_bytes (const void *, size_t); +void filesys_stub_put_file (struct file *); +void filesys_stub_put_int32 (int32_t); +void filesys_stub_put_string (const char *); +void filesys_stub_put_uint32 (uint32_t); + +bool filesys_stub_get_bool (void); +void filesys_stub_get_bytes (void *, size_t); +struct file *filesys_stub_get_file (void); +int32_t filesys_stub_get_int32 (void); +void filesys_stub_match_string (const char *); +uint32_t filesys_stub_get_uint32 (void); #endif /* filesys-stub.h */ diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c index 6b7710a..f8348ed 100644 --- a/src/filesys/filesys.c +++ b/src/filesys/filesys.c @@ -1,37 +1,90 @@ #include "filesys.h" + #ifdef FILESYS_STUB +#include +#include "debug.h" +#include "filesys-stub.h" +#include "lib.h" + void filesys_init (bool reformat) { if (reformat) printk ("filesystem stubs don't support formatting\n"); + filesys_stub_init (); } bool filesys_create (const char *name) { - bool success = false; - filesys_stub_send ("s'create' s", name); - filesys_stub_receive ("s'create' b", &success); + bool success; + + filesys_stub_lock (); + filesys_stub_put_string ("create"); + filesys_stub_put_string (name); + filesys_stub_match_string ("create"); + success = filesys_stub_get_bool (); + filesys_stub_unlock (); + return success; } struct file * filesys_open (const char *name) { - int32_t handle = -1; - filesys_stub_stub ("s'open' i", name); - filesys_stub_receive ("s'open' i", &handle); - return handle == -1 ? NULL : (struct file *) handle; + struct file *file; + + filesys_stub_lock (); + filesys_stub_put_string ("open"); + filesys_stub_put_string (name); + filesys_stub_match_string ("open"); + file = filesys_stub_get_file (); + filesys_stub_unlock (); + + return file; } bool filesys_remove (const char *name) { - bool success = false; - filesys_stub_send ("s'create' s", name); - filesys_stub_receive ("s'create' b", &success); + bool success; + + filesys_stub_lock (); + filesys_stub_put_string ("remove"); + filesys_stub_put_string (name); + filesys_stub_match_string ("remove"); + success = filesys_stub_get_bool (); + filesys_stub_unlock (); + return success; } #endif /* FILESYS_STUB */ + +#undef NDEBUG +#include "debug.h" +#include "file.h" + +void +filesys_self_test (void) +{ + static const char s[] = "This is a test string."; + struct file *file; + char s2[sizeof s]; + + ASSERT (filesys_create ("foo")); + ASSERT ((file = filesys_open ("foo")) != NULL); + ASSERT (file_write (file, s, sizeof s) == sizeof s); + ASSERT (file_tell (file) == sizeof s); + ASSERT (file_length (file) == sizeof s); + file_close (file); + + ASSERT ((file = filesys_open ("foo")) != NULL); + ASSERT (file_read (file, s2, sizeof s2) == sizeof s2); + ASSERT (memcmp (s, s2, sizeof s) == 0); + ASSERT (file_tell (file) == sizeof s2); + ASSERT (file_length (file) == sizeof s2); + file_close (file); + + ASSERT (filesys_remove ("foo")); +} diff --git a/src/filesys/filesys.h b/src/filesys/filesys.h index 6f1e387..bbde398 100644 --- a/src/filesys/filesys.h +++ b/src/filesys/filesys.h @@ -8,4 +8,6 @@ bool filesys_create (const char *name); struct file *filesys_open (const char *name); bool filesys_remove (const char *name); +void filesys_self_test (void); + #endif /* filesys.h */ diff --git a/src/lib/backdoor.c b/src/lib/backdoor.c index ac90f3c..efb1b4c 100644 --- a/src/lib/backdoor.c +++ b/src/lib/backdoor.c @@ -3,8 +3,9 @@ #include #include -static void -marshal_int32 (int32_t value, void (*out) (uint8_t, void *aux), void *aux) +void +backdoor_put_int32 (int32_t value, + void (*out) (uint8_t, void *aux), void *aux) { out ((value >> 24) & 0xff, aux); out ((value >> 16) & 0xff, aux); @@ -12,9 +13,19 @@ marshal_int32 (int32_t value, void (*out) (uint8_t, void *aux), void *aux) out (value & 0xff, aux); } -static void -marshal_bytes (const void *buffer, size_t cnt, - void (*out) (uint8_t, void *aux), void *aux) +void +backdoor_put_uint32 (uint32_t value, + void (*out) (uint8_t, void *aux), void *aux) +{ + out ((value >> 24) & 0xff, aux); + out ((value >> 16) & 0xff, aux); + out ((value >> 8) & 0xff, aux); + out (value & 0xff, aux); +} + +void +backdoor_put_bytes (const void *buffer, size_t cnt, + void (*out) (uint8_t, void *aux), void *aux) { const uint8_t *p = buffer; size_t i; @@ -23,196 +34,64 @@ marshal_bytes (const void *buffer, size_t cnt, out (p[i], aux); } -enum backdoor_error -backdoor_vmarshal (const char *types, va_list args, - void (*out) (uint8_t, void *aux), void *aux) +void +backdoor_put_string (const char *string, + void (*out) (uint8_t, void *aux), void *aux) { - const char *p = types; - - for (;;) - { - /* Find next type character. */ - while (*p == ' ') - p++; - if (*p == '\0') - return BACKDOOR_OK; - - out (*p, aux); - switch (*p++) - { - case 's': - if (*p == '\'') - { - const char *end = strchr (++p, '\''); - marshal_int32 (end - p, out, aux); - marshal_bytes (p, end - p, out, aux); - p = end + 1; - } - else - { - const char *s = va_arg (args, const char *); - marshal_int32 (strlen (s), out, aux); - marshal_bytes (s, strlen (s), out, aux); - } - break; - - case 'i': - marshal_int32 (va_arg (args, int32_t), out, aux); - break; - - case 'B': - { - const void *buffer = va_arg (args, const void *); - size_t size = va_arg (args, size_t); - marshal_int32 (size, out, aux); - marshal_bytes (buffer, size, out, aux); - } - break; + size_t length = strlen (string); - case 'b': - marshal_int32 (va_arg (args, int), out, aux); - break; + backdoor_put_uint32 (length, out, aux); + backdoor_put_bytes (string, length, out, aux); +} - default: - return BACKDOOR_BAD_TYPE; - } - } +void +backdoor_put_bool (bool b, + void (*out) (uint8_t, void *aux), void *aux) +{ + backdoor_put_uint32 (b, out, aux); } -static bool -unmarshal_int32 (int32_t *value, - bool (*in) (uint8_t *, void *aux), void *aux) +int32_t +backdoor_get_int32 (uint8_t (*in) (void *aux), void *aux) { - int32_t tmp; + int32_t value; int i; - tmp = 0; - for (i = 0; i < 4; i++) - { - uint8_t b; - if (!in (&b, aux)) - return false; + value = 0; + for (i = 0; i < 4; i++) + value = (value << 8) | in (aux); + return value; +} - tmp = (tmp << 8) | b; - } - *value = tmp; - return true; +uint32_t +backdoor_get_uint32 (uint8_t (*in) (void *aux), void *aux) +{ + return backdoor_get_int32 (in, aux); } -static bool -unmarshal_bytes (void *buffer, size_t cnt, - bool (*in) (uint8_t *, void *aux), void *aux) +char * +backdoor_get_string (uint8_t (*in) (void *aux), void *aux) +{ + size_t length = backdoor_get_uint32 (in, aux); + char *string = malloc (length + 1); + backdoor_get_bytes (string, length, in, aux); + string[length] = '\0'; + return string; +} + +void +backdoor_get_bytes (void *buffer, size_t cnt, + uint8_t (*in) (void *aux), void *aux) { uint8_t *p = buffer; size_t i; - for (i = 0; i < cnt; i++) - if (!in (&p[i], aux)) - return false; - return true; + for (i = 0; i < cnt; i++) + p[i] = in (aux); } -enum backdoor_error -backdoor_vunmarshal (const char *types, va_list args, - bool (*in) (uint8_t *, void *aux), void *aux) +bool +backdoor_get_bool (uint8_t (*in) (void *aux), void *aux) { - const char *p = types; - - for (;;) - { - uint8_t c; - - /* Find next type character. */ - while (*p == ' ') - p++; - if (*p == '\0') - return BACKDOOR_OK; - - /* Check type character in input. */ - if (!in (&c, aux)) - return BACKDOOR_UNEXPECTED_EOF; - if (c != *p++) - return BACKDOOR_TYPE_MISMATCH; - - switch (c) - { - case 's': - { - int32_t length; - - if (!unmarshal_int32 (&length, in, aux)) - return BACKDOOR_UNEXPECTED_EOF; - if (length < 0) - return BACKDOOR_NEGATIVE_SIZE; - if (*p == '\'') - { - const char *end = strchr (++p, '\''); - if (length != end - p) - return BACKDOOR_STRING_MISMATCH; - while (p < end) - { - uint8_t q; - if (!in (&q, aux)) - return BACKDOOR_UNEXPECTED_EOF; - if (q != *p++) - return BACKDOOR_STRING_MISMATCH; - } - p++; - } - else - { - char *s = malloc (length + 1); - if (s == NULL) - return BACKDOOR_NOMEM; - if (!unmarshal_bytes (s, length, in, aux)) - { - free (s); - return BACKDOOR_UNEXPECTED_EOF; - } - s[length] = '\0'; - *va_arg (args, char **) = s; - } - } - break; - - case 'i': - if (!unmarshal_int32 (va_arg (args, int32_t *), in, aux)) - return BACKDOOR_UNEXPECTED_EOF; - break; - - case 'B': - { - int32_t size; - void *buffer; - - if (!unmarshal_int32 (&size, in, aux)) - return BACKDOOR_UNEXPECTED_EOF; - if (size < 0) - return BACKDOOR_NEGATIVE_SIZE; - buffer = malloc (size); - if (size > 0 && buffer == NULL) - return BACKDOOR_NOMEM; - if (!unmarshal_bytes (buffer, size, in, aux)) - { - free (buffer); - return BACKDOOR_UNEXPECTED_EOF; - } - *va_arg (args, size_t *) = size; - *va_arg (args, void **) = buffer; - } - break; - - case 'b': - { - int32_t b; - if (!unmarshal_int32 (&b, in, aux)) - return BACKDOOR_UNEXPECTED_EOF; - *va_arg (args, bool *) = b; - } - break; - - default: - return BACKDOOR_BAD_TYPE; - } - } + return backdoor_get_uint32 (in, aux) != 0; } diff --git a/src/lib/backdoor.h b/src/lib/backdoor.h index 8205aa3..e999679 100644 --- a/src/lib/backdoor.h +++ b/src/lib/backdoor.h @@ -4,23 +4,31 @@ #include #include #include +#include -enum backdoor_error - { - BACKDOOR_OK = 0, - BACKDOOR_NOMEM = -100, - BACKDOOR_BAD_TYPE, - BACKDOOR_TYPE_MISMATCH, - BACKDOOR_STRING_MISMATCH, - BACKDOOR_NEGATIVE_SIZE, - BACKDOOR_UNEXPECTED_EOF - }; - -enum backdoor_error -backdoor_vmarshal (const char *types, va_list args, - void (*) (uint8_t, void *aux), void *aux); -enum backdoor_error -backdoor_vunmarshal (const char *types, va_list args, - bool (*) (uint8_t *, void *aux), void *aux); +#ifdef __cplusplus +extern "C" { +#endif + +void backdoor_put_int32 (int32_t value, + void (*out) (uint8_t, void *aux), void *aux); +void backdoor_put_uint32 (uint32_t value, + void (*out) (uint8_t, void *aux), void *aux); +void backdoor_put_bytes (const void *buffer, size_t cnt, + void (*out) (uint8_t, void *aux), void *aux); +void backdoor_put_string (const char *string, + void (*out) (uint8_t, void *aux), void *aux); +void backdoor_put_bool (bool b, + void (*out) (uint8_t, void *aux), void *aux); +int32_t backdoor_get_int32 (uint8_t (*in) (void *aux), void *aux); +uint32_t backdoor_get_uint32 (uint8_t (*in) (void *aux), void *aux); +char *backdoor_get_string (uint8_t (*in) (void *aux), void *aux); +void backdoor_get_bytes (void *buffer, size_t cnt, + uint8_t (*in) (void *aux), void *aux); +bool backdoor_get_bool (uint8_t (*in) (void *aux), void *aux); + +#ifdef __cplusplus +}; +#endif #endif /* backdoor.h */ diff --git a/src/threads/init.c b/src/threads/init.c index 453543f..f8c5f5a 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -14,6 +14,9 @@ #include "thread.h" #include "timer.h" #include "vga.h" +#ifdef FILESYS +#include "filesys.h" +#endif /* Size of kernel static code and data, in 4 kB pages. */ size_t kernel_pages; @@ -38,7 +41,7 @@ tfunc (void *aux UNUSED) printk ("%s exiting\n", thread_current ()->name); break; } - count = random_ulong () % 25 * 1000000; + count = random_ulong () % 25 * 10000; printk ("%s waiting %zu: ", thread_current ()->name, count); for (i = 0; i < count; i++); printk ("%s\n", thread_current ()->name); @@ -78,7 +81,10 @@ main (void) intr_init (); timer_init (); kbd_init (); - intr_enable (); + +#ifdef FILESYS + filesys_init (false); +#endif thread_init (); diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index f368385..3ae5050 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -260,7 +260,6 @@ intr_unexpected (struct intr_args *regs) { uint32_t cr2; asm ("movl %%cr2, %0" : "=r" (cr2)); - printk ("Unexpected interrupt 0x%02x, error code %08x, cr2=%08x, eip=%08x\n", - regs->vec_no, regs->error_code, cr2, regs->eip); - for (;;); + panic ("Unexpected interrupt 0x%02x, error code %08x, cr2=%08x, eip=%08x", + regs->vec_no, regs->error_code, cr2, regs->eip); } diff --git a/src/threads/intr-stubs.pl b/src/threads/intr-stubs.pl index 45f4fa3..8987c43 100755 --- a/src/threads/intr-stubs.pl +++ b/src/threads/intr-stubs.pl @@ -24,6 +24,7 @@ for $i (0...255) { print <<'EOF'; intr_entry: + # FIXME: build a fake stack frame to improve backtraces. # Save caller's registers. pushl %ds pushl %es diff --git a/src/threads/malloc.c b/src/threads/malloc.c index afa487c..ba39d1d 100644 --- a/src/threads/malloc.c +++ b/src/threads/malloc.c @@ -44,7 +44,7 @@ malloc_init (void) static struct arena * slot_to_arena (struct slot *s) { - return (struct arena *) ((uint32_t) s & (NBPG - 1)); + return (struct arena *) ((uint32_t) s & ~(NBPG - 1)); } static void * diff --git a/src/threads/thread.c b/src/threads/thread.c index 6793bb3..0c3c544 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -112,6 +112,8 @@ thread_schedule (void) { struct thread *cur, *next, *prev; + ASSERT (intr_get_level () == IF_OFF); + cur = thread_current (); ASSERT (cur->status != THREAD_RUNNING); @@ -120,14 +122,23 @@ thread_schedule (void) next->status = THREAD_RUNNING; prev = thread_switch (cur, next); + + /* Prevent GCC from reordering anything around the thread + switch. */ + asm volatile ("" : : : "memory"); + if (prev != NULL && prev->status == THREAD_DYING) thread_destroy (prev); + + intr_enable (); } void thread_yield (void) { ASSERT (!intr_context ()); + + intr_disable (); thread_ready (thread_current ()); thread_schedule (); } @@ -135,6 +146,8 @@ thread_yield (void) void thread_start (struct thread *t) { + ASSERT (intr_get_level () == IF_OFF); + if (t->status == THREAD_READY) list_remove (&t->rq_elem); t->status = THREAD_RUNNING; @@ -144,14 +157,17 @@ thread_start (struct thread *t) void thread_exit (void) { - struct thread *t = thread_current (); - t->status = THREAD_DYING; + ASSERT (!intr_context ()); + + intr_disable (); + thread_current ()->status = THREAD_DYING; thread_schedule (); } void thread_sleep (void) { + ASSERT (!intr_context ()); ASSERT (intr_get_level () == IF_OFF); thread_current ()->status = THREAD_BLOCKED;