RANDOM_REPLACEMENT, extra credit. Update documentation, grading.
project, so you don't need to make sure that the previous projects also
compile.
-@node Conditional Compilation
-@section Conditional Compilation
-
-Given the scope and complexity of your assignments this quarter, you
-may find it convenient while coding and debugging (and we will find it
-convenient while grading) to be able to independently turn different
-parts of the assignments on and off. To do this, choose a macro name
-and use it in conditional
-compilation directives, e.g.:
-
-@example
-#ifdef @var{NAME}
-@dots{}your code@dots{}
-#endif
-@end example
-
-In general, the code that you turn in must not depend on conditional
-compilation directives. Project code should be written so that all of
-the subproblems for the project function together, and it should
-compile properly without the need for any new macros to be defined.
-There are a few exceptions:
-
-@itemize @bullet
-@item
-Problem 1-3, the advanced scheduler. We must be able to turn this on
-and off with a compile-time directive. You must use the macro name we
-specify for that part. @xref{Problem 1-3 Advanced Scheduler}, for
-details.
-
-@item
-Problem 3-2, paging to and from disk. Your page replacement policy must
-default to LRU-like replacement, but we must be able to choose a random
-replacement policy with a compile-time directive. You must use the
-macro name we specify for that part. @xref{Problem 3-2 Paging To and
-From Disk}, for details.
-
-@item
-Code written for extra credit may be included conditionally. If the
-extra credit code changes the normally expected functionality of the
-code, then it @emph{must} be included conditionally, and it must not
-be enabled by default.
-@end itemize
-
-You can use @file{constants.h} in @file{pintos/src} to define macros
-for conditional compilation. We will replace the @file{constants.h}
-that you supply with one of our own when we test your code, so do not
-define anything important in it.
+Project code should be written so that all of the subproblems for the
+project function together, that is, without the need to rebuild with
+different macros defined, etc. If you do extra credit work that
+changes normal Pintos behavior so as to interfere with grading, then
+you must implement it so that it only acts that way when given a
+special command-line option of the form @option{-o @var{name}}, where
+@var{name} is a name of your choice. You can add such an option by
+modifying @func{argv_init} in @file{threads/init.c}.
@node C99
@section C99
at least one workload of your own design (i.e.@: in addition to the
provided test).
-You must write your code so that we can turn the MLFQS on and off at
-compile time. By default, it must be off, but we must be able to turn
-it on by inserting the line @code{#define MLFQS 1} in
-@file{constants.h}. @xref{Conditional Compilation}, for details.
+You must write your code so that we can choose a scheduling algorithm
+policy at Pintos startup time. By default, the round-robin scheduler
+must be active, but we must be able to choose the MLFQS by invoking
+@command{pintos} with the @option{-o mlfqs} option. Passing this
+option sets @code{enable_mlfqs}, declared in @file{threads/init.h}, to
+true.
@node Threads FAQ
@section FAQ
page replacement policy. The canonical example of a poor page
replacement policy is random replacement.
-You must write your code so that we can choose a page replacement policy
-at compile time. By default, the LRU-like algorithm must be in effect,
-but we must be able to choose random replacement by inserting the line
-@code{#define RANDOM_REPLACEMENT 1} in @file{constants.h}.
-@xref{Conditional Compilation}, for details.
+You must write your code so that we can choose a page replacement
+policy at Pintos startup time. By default, the LRU-like algorithm
+must be in effect, but we must be able to choose random replacement by
+invoking @command{pintos} with the @option{-o random-paging} option.
+Passing this option sets @code{enable_random_paging}, declared in
+@file{threads/init.h}, to true.
Since you will already be paging from disk, you should implement a
``lazy'' loading scheme for new processes. When a process is created,
\f
# Source tarballs.
-# Extracts the group's source files into pintos/src,
-# applies any patches providing in the grading directory,
-# and installs a default pintos/src/constants.h
+# Extracts the group's source files into pintos/src
+# and applies any patches providing in the grading directory.
sub extract_sources {
# Make sure the output dir exists.
-d ("output") || mkdir ("output") or die "output: mkdir: $!\n";
xsystem ("patch -fs -p0 < $patch",
LOG => $stem, DIE => "applying patch $stem failed\n");
}
-
- # Install default pintos/src/constants.h (which is empty).
- open (CONSTANTS, ">pintos/src/constants.h")
- or die "constants.h: create: $!\n";
- close CONSTANTS;
}
# Returns the name of the tarball to extract.
#include "threads/thread.h"
#include "devices/timer.h"
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
static void test_sleep (int thread_cnt, int iterations);
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
test_sleep (5, 7);
}
\f
#include "threads/thread.h"
#include "devices/timer.h"
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
static void test_sleep (int thread_cnt, int iterations);
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
test_sleep (5, 1);
}
\f
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "threads/synch.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "threads/synch.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "threads/synch.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "devices/timer.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "threads/synch.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
# Runs $test in directory output/$test.
# Returns 'ok' if it went ok, otherwise an explanation.
sub run_test {
- # Change constants.h if necessary.
- my ($defines) = $test ne 'mlfqs-on' ? "" : "#define MLFQS 1\n";
- if ($defines ne snarf ("pintos/src/constants.h")) {
- open (CONSTANTS, ">pintos/src/constants.h");
- print CONSTANTS $defines;
- close (CONSTANTS);
- }
-
# Changes devices/timer.c if necessary.
my ($new_time_slice) = $test eq 'priority-fifo' ? 100 : 1;
my (@timer_c) = snarf ("pintos/src/devices/timer.c");
# Run.
my ($timeout) = $test !~ /^mlfqs/ ? 15 : 600;
- return run_pintos (["-v", "run", "-q"],
+ my (@command) = ("-v", "run", "-q");
+ push (@command, "-o mlfqs") if $test eq 'mlfqs-on';
+ return run_pintos (\@command,
CHDIR => "pintos/src/threads/build",
LOG => "$test/run",
TIMEOUT => $timeout);
# Compiler and assembler options.
DEFINES += -DKERNEL
-CPPFLAGS = -nostdinc -I../.. -I- -I../../lib -I../../lib/kernel \
- -include constants.h
+CPPFLAGS = -nostdinc -I../.. -I- -I../../lib -I../../lib/kernel
# Core kernel.
threads_SRC = threads/init.c # Main program.
+++ /dev/null
-/* Use this header file to define macros for configuring
- compilation. This file will be replaced by the TAs when your
- code is tested, using the macros described in the course
- documentation. Your code should not require other macros to
- be defined here to function properly. */
-
-/* Example definition. */
-/*#define MACRONAME 1 */
#include "threads/thread.h"
#include "devices/timer.h"
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
static void test_sleep (int thread_cnt, int iterations);
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Easy test: 5 threads sleep once each. */
test_sleep (5, 1);
<gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
Modified by arens. */
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
#include "threads/test.h"
#include <stdio.h>
#include "threads/synch.h"
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Make sure our priority is the default. */
ASSERT (thread_get_priority () == PRI_DEFAULT);
/* Page directory with kernel mappings only. */
uint32_t *base_page_dir;
-#ifdef FILESYS
-/* -f: Format the filesystem? */
-static bool format_filesys;
-#endif
+/* -o mlfqs:
+ If false (default), use round-robin scheduler.
+ If true, use multi-level feedback queue scheduler. */
+bool enable_mlfqs;
#ifdef USERPROG
/* -ex: Initial program to run. */
static char *initial_program;
#endif
+#ifdef VM
+/* -o random-paging:
+ If false (default), use LRU page replacement policy.
+ If true, use random page replacement policy. */
+bool enable_random_paging;
+#endif
+
+#ifdef FILESYS
+/* -f: Format the filesystem? */
+static bool format_filesys;
+#endif
+
/* -q: Power off after kernel tasks complete? */
bool power_off_when_done;
/* Parse the words. */
for (i = 0; i < argc; i++)
- if (!strcmp (argv[i], "-rs"))
+ if (!strcmp (argv[i], "-o"))
+ {
+ i++;
+ if (!strcmp (argv[i], "mlfqs"))
+ enable_mlfqs = true;
+#ifdef VM
+ else if (!strcmp (argv[i], "random-paging"))
+ enable_random_paging = true;
+#endif
+ else
+ PANIC ("unknown option `-o %s' (use -u for help)", argv[i]);
+ }
+ else if (!strcmp (argv[i], "-rs"))
random_init (atoi (argv[++i]));
else if (!strcmp (argv[i], "-q"))
power_off_when_done = true;
{
printf (
"Kernel options:\n"
- " -rs SEED Set random seed to SEED.\n"
+ " -o mlfqs Use multi-level feedback queue scheduler.\n"
#ifdef USERPROG
" -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
" -ul USER_MAX Limit user memory to USER_MAX pages.\n"
#endif
+#ifdef VM
+ " -o random-paging Use random page replacement policy.\n"
+#endif
#ifdef FILESYS
" -f Format the filesystem disk (hdb or hd0:1).\n"
" -ci FILE SIZE Copy SIZE bytes from the scratch disk (hdc\n"
" -r FILE Delete FILE.\n"
" -ls List files in the root directory.\n"
#endif
+ " -rs SEED Set random seed to SEED.\n"
" -q Power off after doing requested actions.\n"
" -u Print this help message and power off.\n"
);
/* Page directory with kernel mappings only. */
extern uint32_t *base_page_dir;
+/* -o mlfqs:
+ If false (default), use round-robin scheduler.
+ If true, use multi-level feedback queue scheduler. */
+extern bool enable_mlfqs;
+
+#ifdef VM
+/* -o random-paging:
+ If false (default), use LRU page replacement policy.
+ If true, use random page replacement policy. */
+extern bool enable_random_paging;
+#endif
+
/* -q: Power off when kernel tasks complete? */
extern bool power_off_when_done;
#include "threads/thread.h"
#include "devices/timer.h"
-#ifdef MLFQS
-#error This test not applicable with MLFQS enabled.
-#endif
-
static void test_sleep (int thread_cnt, int iterations);
void
test (void)
{
+ /* This test does not work with the MLFQS. */
+ ASSERT (!enable_mlfqs);
+
/* Easy test: 5 threads sleep once each. */
test_sleep (5, 1);
#ifndef THREADS_TEST_H
#define THREADS_TEST_H
+#include "threads/init.h"
+
void test (void);
#endif /* threads/test.h */