X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Fsynch.c;h=169128d8ba62e84e3d6d738a9237988716023bb4;hb=f2f8875638593bd5365cfd6a5ba7c9578e52322f;hp=08ba8f4b90cff42b698ab89a99f7c19d65ba45f6;hpb=349cc721b17effa62c8b18a7dccc5defc44472d3;p=pintos-anon diff --git a/src/threads/synch.c b/src/threads/synch.c index 08ba8f4..169128d 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -1,14 +1,36 @@ -#include "synch.h" -#include "interrupt.h" -#include "lib.h" -#include "thread.h" - -/* One thread in a list. */ -struct thread_elem - { - list_elem elem; - struct thread *thread; - }; +/* This file is derived from source code for the Nachos + instructional operating system. The Nachos copyright notice + is reproduced in full below. */ + +/* Copyright (c) 1992-1996 The Regents of the University of California. + All rights reserved. + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose, without fee, and + without written agreement is hereby granted, provided that the + above copyright notice and the following two paragraphs appear + in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO + ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE + AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA + HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR + MODIFICATIONS. +*/ + +#include "threads/synch.h" +#include +#include +#include "threads/interrupt.h" +#include "threads/thread.h" /* Initializes semaphore SEMA to VALUE and names it NAME (for debugging purposes only). A semaphore is a nonnegative @@ -30,8 +52,8 @@ sema_init (struct semaphore *sema, unsigned value, const char *name) list_init (&sema->waiters); } -/* Waits for SEMA's value to become positive and then - atomically decrements it. +/* Down or "P" operation on a semaphore. Waits for SEMA's value + to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with @@ -48,17 +70,15 @@ sema_down (struct semaphore *sema) old_level = intr_disable (); while (sema->value == 0) { - struct thread_elem te; - te.thread = thread_current (); - list_push_back (&sema->waiters, &te.elem); + list_push_back (&sema->waiters, &thread_current ()->elem); thread_block (); } sema->value--; intr_set_level (old_level); } -/* Increments SEMA's value. Wakes up one thread of those waiting - for SEMA, if any. +/* Up or "V" operation on a semaphore. Increments SEMA's value + and wakes up one thread of those waiting for SEMA, if any. This function may be called from an interrupt handler. */ void @@ -71,7 +91,7 @@ sema_up (struct semaphore *sema) old_level = intr_disable (); if (!list_empty (&sema->waiters)) thread_unblock (list_entry (list_pop_front (&sema->waiters), - struct thread_elem, elem)->thread); + struct thread, elem)); sema->value++; intr_set_level (old_level); } @@ -83,21 +103,10 @@ sema_name (const struct semaphore *sema) return sema->name; } -static void -sema_test_helper (void *sema_) -{ - struct semaphore *sema = sema_; - int i; - - for (i = 0; i < 10; i++) - { - sema_down (&sema[0]); - sema_up (&sema[1]); - } -} +static void sema_test_helper (void *sema_); /* Self-test for semaphores that makes control "ping-pong" - between a pair of threads. Insert calls to printk() to see + between a pair of threads. Insert calls to printf() to see what's going on. */ void sema_self_test (void) @@ -106,6 +115,7 @@ sema_self_test (void) struct semaphore sema[2]; int i; + printf ("Testing semaphores..."); sema_init (&sema[0], 0, "ping"); sema_init (&sema[1], 0, "pong"); thread = thread_create ("sema-test", sema_test_helper, &sema); @@ -114,6 +124,21 @@ sema_self_test (void) sema_up (&sema[0]); sema_down (&sema[1]); } + printf ("done.\n"); +} + +/* Thread function used by sema_self_test(). */ +static void +sema_test_helper (void *sema_) +{ + struct semaphore *sema = sema_; + int i; + + for (i = 0; i < 10; i++) + { + sema_down (&sema[0]); + sema_up (&sema[1]); + } } /* Initializes LOCK and names it NAME (for debugging purposes). @@ -208,8 +233,8 @@ lock_name (const struct lock *lock) /* One semaphore in a list. */ struct semaphore_elem { - list_elem elem; - struct semaphore semaphore; + list_elem elem; /* List element. */ + struct semaphore semaphore; /* This semaphore. */ }; /* Initializes condition variable COND and names it NAME. A @@ -232,9 +257,9 @@ cond_init (struct condition *cond, const char *name) this function. The monitor implemented by this function is "Mesa" style, not - "Hoare" style. That is, sending a signal is not atomic with - delivering it. Thus, typically the caller must recheck the - condition after the wait completes and, if necessary, wait + "Hoare" style, that is, sending and receiving a signal are not + an atomic operation. Thus, typically the caller must recheck + the condition after the wait completes and, if necessary, wait again. A given condition variable is associated with only a single