to date.
Basic interrupt handling and functions for turning interrupts on and
off.
-@item intr-stubs.S
+@item intr-stubs.pl
@itemx intr-stubs.h
-Assembly code for low-level interrupt handling.
+A Perl program that outputs assembly for low-level interrupt handling.
@item synch.c
@itemx synch.h
Be careful to program this function correctly. You will need its
functionality for project 2.
+Once you've implemented @func{thread_join}, define
+@code{THREAD_JOIN_IMPLEMENTED} in @file{constants.h}.
+@xref{Conditional Compilation}, for more information.
+
@node Problem 1-3 Priority Scheduling
@section Problem 1-3: Priority Scheduling
IDT so that each entry points to a unique entry point in
@file{threads/intr-stubs.S} named @func{intr@var{NN}_stub}, where
@var{NN} is the interrupt number in
-hexadecimal. Because the CPU doesn't give
+hexadecimal.@footnote{@file{threads/intr-stubs.S} is so repetitive
+that it is actually generated by a Perl script,
+@file{threads/intr-stubs.pl}. Thus, you will actually find
+@file{threads/intr-stubs.S} in your @file{threads/build/threads}
+directory, not in plain @file{threads}.} Because the CPU doesn't give
us any other way to find out the interrupt number, this entry point
pushes the interrupt number on the stack. Then it jumps to
@func{intr_entry}, which pushes all the registers that the processor
You will continue to handle Pintos disks and file systems the same way
you did in the previous assignment (@pxref{Using the File System}).
+Your submission should define @code{THREAD_JOIN_IMPLEMENTED} in
+@file{constants.h} (@pxref{Conditional Compilation}).
+
@menu
* VM Design::
* Page Faults::
LOG => $stem, DIE => "applying patch $stem failed\n");
}
- # Install default pintos/src/constants.h (which is empty).
+ # Install default pintos/src/constants.h.
open (CONSTANTS, ">pintos/src/constants.h")
or die "constants.h: create: $!\n";
+ print CONSTANTS "#define THREAD_JOIN_IMPLEMENTED 1\n";
close CONSTANTS;
}
sub run_test {
# Change constants.h if necessary.
my ($defines) = $test ne 'mlfqs-on' ? "" : "#define MLFQS 1\n";
+ $defines .= "#define THREAD_JOIN_IMPLEMENTED 1\n";
if ($defines ne snarf ("pintos/src/constants.h")) {
open (CONSTANTS, ">pintos/src/constants.h");
print CONSTANTS $defines;
/* Interrupt stack frame. */
struct intr_frame
{
- /* Pushed by intr_entry in intr-stubs.S.
+ /* Pushed by intr_entry in intr-stubs.S (see intr-stubs.pl).
These are the interrupted task's saved registers. */
uint32_t edi; /* Saved EDI. */
uint32_t esi; /* Saved ESI. */
uint16_t es, :16; /* Saved ES segment register. */
uint16_t ds, :16; /* Saved DS segment register. */
- /* Pushed by intrNN_stub in intr-stubs.S. */
+ /* Pushed by intrXX_stub in intr-stubs.S (see intr-stubs.pl). */
uint32_t vec_no; /* Interrupt vector number. */
/* Sometimes pushed by the CPU,
- otherwise for consistency pushed as 0 by intrNN_stub.
- The CPU puts it just under `eip', but we move it here. */
+ otherwise for consistency pushed as 0 by intrXX_stub. */
uint32_t error_code; /* Error code. */
- /* Pushed by intrNN_stub in intr-stubs.S.
- This frame pointer eases interpretation of backtraces. */
- void *frame_pointer; /* Saved EBP (frame pointer). */
-
/* Pushed by the CPU.
These are the interrupted task's saved registers. */
void (*eip) (void); /* Next instruction to execute. */
--- /dev/null
+#! /usr/bin/perl
+
+print <<'EOF';
+#include "threads/loader.h"
+
+ .data
+ .intel_syntax noprefix
+.globl intr_stubs
+intr_stubs:
+EOF
+
+for $i (0...255) {
+ $x = sprintf ("%02x", $i);
+ print "\t.long intr${x}_stub\n";
+}
+
+print <<'EOF';
+
+ .text
+EOF
+
+for $i (0...255) {
+ $x = sprintf ("%02x", $i);
+ print ".globl intr${x}_stub\n";
+ print "intr${x}_stub:\n";
+ print "\tpush 0\n"
+ if ($i != 8 && $i != 10 && $i != 11
+ && $i != 13 && $i != 14 && $i != 17);
+ print "\tpush 0x$x\n";
+ print "\tjmp intr_entry\n";
+}
+
+print <<'EOF';
+intr_entry:
+ # Save caller's registers.
+ push ds
+ push es
+ push fs
+ push gs
+ pusha
+
+ # Set up kernel environment.
+ cld
+ mov eax, SEL_KDSEG
+ mov ds, eax
+ mov es, eax
+
+ # Call interrupt handler.
+ push esp
+.globl intr_handler
+ call intr_handler
+ add esp, 4
+
+.globl intr_exit
+intr_exit:
+ # Restore caller's registers.
+ popa
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ add esp, 8
+
+ # Return to caller.
+ iret
+EOF
schedule ();
intr_set_level (old_level);
}
-
-/* Waits for the thread with the specified TID to terminate. If
- TID has already terminated or TID does not refer to an
- immediate child of the current thread, returns immediately.
-
- This function will be implemented in problem 1-2. For now, it
- does nothing. */
-void
-thread_join (tid_t child_tid UNUSED)
-{
-}
-
-/* Sets the current thread's priority to NEW_PRIORITY. */
-void
-thread_set_priority (int new_priority)
-{
- thread_current ()->priority = new_priority;
-}
-
-/* Returns the current thread's priority. */
-int
-thread_get_priority (void)
-{
- return thread_current ()->priority;
-}
\f
/* Idle thread. Executes when no other thread is ready to run. */
static void
check:
$(MAKE) -C .. distclean
+ $(MAKE) check-noclean
+
+check-noclean:
for d in $(TESTS); do $(MAKE) $$d || exit 1; done
@echo All tests passed.
$(prep-grading)
$(mk-sandbox)
$(apply-patch) ../solutions/p1-2.patch
+ echo '#define THREAD_JOIN_IMPLEMENTED 1' > $@/pintos/src/constants.h
$(run-tests) null
$(clean)