same time. Plus, keeping VM is a great way to stress-test your
filesystem implementation.
-Your submission should define @code{THREAD_JOIN_IMPLEMENTED} in
-@file{constants.h} (@pxref{Conditional Compilation}).
-
@menu
* File System New Code::
* File System Synchronization::
There are a few exceptions:
@itemize @bullet
-@item
-Problem 1-2, @func{thread_join}. Some other code expects
-@code{THREAD_JOIN_IMPLEMENTED} to be defined once you've implemented
-this function.
-
@item
Problem 1-4, 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
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
relevant parts below. If you are confident in your HW1 code, you can
build on top of it. However, if you wish you can start with a fresh
copy of the code and re-implement @func{thread_join}, which is the
-only part of project #1 required for this assignment. Your submission
-should define @code{THREAD_JOIN_IMPLEMENTED} in @file{constants.h}
-(@pxref{Conditional Compilation}).
+only part of project #1 required for this assignment.
Up to now, all of the code you have written for Pintos has been part
of the operating system kernel. This means, for example, that all the
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.
+ # Install default pintos/src/constants.h (which is empty).
open (CONSTANTS, ">pintos/src/constants.h")
or die "constants.h: create: $!\n";
- print CONSTANTS "#define THREAD_JOIN_IMPLEMENTED 1\n";
close CONSTANTS;
}
schedule ();
NOT_REACHED ();
}
-@@ -270,6 +290,22 @@ thread_block (void)
- thread_current ()->status = THREAD_BLOCKED;
- schedule ();
- }
-+
-+/* Waits for thread with tid CHILD_TID to die. */
-+void
+@@ -283,8 +290,18 @@ thread_block (void)
+ This function will be implemented in problem 1-2. For now, it
+ does nothing. */
+ void
+-thread_join (tid_t child_tid UNUSED)
+-{
+thread_join (tid_t child_tid)
+{
+ struct thread *cur = thread_current ();
+ if (child->tid == child_tid)
+ latch_acquire (&child->ready_to_die);
+ }
-+}
- \f
- /* Idle thread. Executes when no other thread is ready to run. */
- static void
+ }
+
+ /* Sets the current thread's priority to NEW_PRIORITY. */
@@ -335,6 +371,9 @@ init_thread (struct thread *t, const cha
strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE;
t->status = THREAD_READY;
intr_set_level (old_level);
}
-@@ -266,11 +280,79 @@ thread_yield (void)
+@@ -266,8 +280,8 @@ thread_yield (void)
ASSERT (!intr_context ());
old_level = intr_disable ();
schedule ();
intr_set_level (old_level);
}
+@@ -274,19 +288,74 @@
+ {
+ }
+
+-/* 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;
+-}
+
+/* Sets the current thread's priority to PRIORITY. */
+void
-Index: src/constants.h
-===================================================================
-RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/constants.h,v
-retrieving revision 1.4
-diff -u -p -r1.4 constants.h
---- src/constants.h 19 Oct 2004 17:37:30 -0000 1.4
-+++ src/constants.h 1 Jan 2005 02:13:41 -0000
-@@ -8,4 +8,4 @@
- /*#define MACRONAME 1 */
-
- /* Uncomment if if you've implemented thread_join(). */
--/*#define THREAD_JOIN_IMPLEMENTED 1*/
-+#define THREAD_JOIN_IMPLEMENTED 1
Index: src/threads/synch.c
===================================================================
RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/threads/synch.c,v
schedule ();
NOT_REACHED ();
}
-@@ -300,6 +323,26 @@ kernel_thread (thread_func *function, vo
- function (aux); /* Execute the thread function. */
- thread_exit (); /* If function() returns, kill the thread. */
- }
-+
-+/* Waits for thread with tid CHILD_TID to die. */
+@@ -283,8 +290,22 @@ thread_block (void)
+ This function will be implemented in problem 1-2. For now, it
+ does nothing. */
+-void
+-thread_join (tid_t child_tid UNUSED)
+-{
+int
+thread_join (tid_t child_tid)
+{
+ if (child->tid == child_tid)
+ {
+ latch_acquire (&child->ready_to_die);
-+ return child->exit_code;
++ return child->exit_code;
+ }
+ }
+ return -1;
-+}
- \f
- /* Returns the running thread. */
- struct thread *
+ }
+
+ /* Sets the current thread's priority to NEW_PRIORITY. */
@@ -336,6 +379,12 @@ init_thread (struct thread *t, const cha
strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE;
/* Owned by thread.c. */
@@ -120,7 +132,7 @@ void thread_exit (void) NO_RETURN;
+ void thread_exit (void) NO_RETURN;
void thread_yield (void);
- /* This function will be implemented in problem 1-2. */
-void thread_join (tid_t);
+int thread_join (tid_t);
- /* These functions will be implemented in problem 1-3. */
void thread_set_priority (int);
+ int thread_get_priority (void);
Index: src/userprog/exception.c
===================================================================
RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/userprog/exception.c,v
# Filesystem code.
filesys_SRC = filesys/filesys.c # Filesystem core.
-diff -urpN pintos.orig/src/constants.h pintos/src/constants.h
---- pintos.orig/src/constants.h 2004-09-21 17:26:39.000000000 -0700
-+++ pintos/src/constants.h 2004-09-27 13:29:43.000000000 -0700
-@@ -8,4 +8,4 @@
- /*#define MACRONAME 1 */
-
- /* Uncomment if if you've implemented thread_join(). */
--/*#define THREAD_JOIN_IMPLEMENTED 1*/
-+#define THREAD_JOIN_IMPLEMENTED 1
diff -urpN pintos.orig/src/threads/init.c pintos/src/threads/init.c
--- pintos.orig/src/threads/init.c 2004-09-26 14:15:17.000000000 -0700
+++ pintos/src/threads/init.c 2004-09-27 16:08:03.000000000 -0700
schedule ();
NOT_REACHED ();
}
-@@ -270,6 +293,26 @@ thread_block (void)
- thread_current ()->status = THREAD_BLOCKED;
- schedule ();
- }
-+
-+/* Waits for thread with tid CHILD_TID to die. */
+@@ -283,8 +290,22 @@ thread_block (void)
+ This function will be implemented in problem 1-2. For now, it
+ does nothing. */
+-void
+-thread_join (tid_t child_tid UNUSED)
+-{
+int
+thread_join (tid_t child_tid)
+{
+ if (child->tid == child_tid)
+ {
+ latch_acquire (&child->ready_to_die);
-+ return child->ret_code;
++ return child->ret_code;
+ }
+ }
+ return -1;
-+}
- \f
- /* Idle thread. Executes when no other thread is ready to run. */
- static void
+ }
+
+ /* Sets the current thread's priority to NEW_PRIORITY. */
@@ -335,6 +378,12 @@ init_thread (struct thread *t, const cha
strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE;
#endif
/* Owned by thread.c */
-@@ -119,7 +133,7 @@ void thread_yield (void);
- void thread_block (void);
+@@ -120,7 +132,7 @@ void thread_exit (void) NO_RETURN;
+ void thread_exit (void) NO_RETURN;
+ void thread_yield (void);
- /* This function will be implemented in problem 1-2. */
-void thread_join (tid_t);
+int thread_join (tid_t);
- /* These functions will be implemented in problem 1-3. */
void thread_set_priority (int);
+ int thread_get_priority (void);
diff -urpN pintos.orig/src/userprog/exception.c pintos/src/userprog/exception.c
--- pintos.orig/src/userprog/exception.c 2004-09-26 14:15:17.000000000 -0700
+++ pintos/src/userprog/exception.c 2004-09-27 13:29:44.000000000 -0700
/* Example definition. */
/*#define MACRONAME 1 */
-
-/* Uncomment if if you've implemented thread_join(). */
-/*#define THREAD_JOIN_IMPLEMENTED 1*/
static thread_func *funcs[] = {io_thread, cpu_thread, io_cpu_thread};
static const char *names[] = {"IO", "CPU", "IO & CPU"};
struct semaphore done[3];
- tid_t tids[3];
int i;
printf ("\n"
for (i = 0; i < 3; i++)
{
sema_init (&done[i], 0, names[i]);
- tids[i] = thread_create (names[i], PRI_DEFAULT, funcs[i], &done[i]);
+ thread_create (names[i], PRI_DEFAULT, funcs[i], &done[i]);
}
/* Wait for threads to finish. */
for (i = 0; i < 3; i++)
- {
-#ifdef THREAD_JOIN_IMPLEMENTED
- thread_join (tids[i]);
-#else
- sema_down (&done[i]);
-#endif
- }
+ sema_down (&done[i]);
printf ("Multilevel feedback queue scheduler test done.\n");
}
tid_t tid;
printf ("\nExecuting '%s':\n", initial_program);
tid = process_execute (initial_program);
-#ifdef THREAD_JOIN_IMPLEMENTED
if (tid != TID_ERROR)
thread_join (tid);
-#endif
}
#else
/* Run the compiled-in test function. */
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
void thread_exit (void) NO_RETURN;
void thread_yield (void);
-/* This function will be implemented in problem 1-2. */
void thread_join (tid_t);
-/* These functions will be implemented in problem 1-3. */
void thread_set_priority (int);
int thread_get_priority (void);
$(prep-grading)
$(mk-sandbox)
$(apply-patch) ../solutions/p1-2.patch
- echo '#define THREAD_JOIN_IMPLEMENTED 1' > $@/pintos/src/constants.h
$(run-tests) null
$(clean)