X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fdevices%2Fintq.c;h=8754c85034d2701d2a07f16dbd9cf48b76fe2673;hb=eb718e3b5a5470b11e58dcc652f79e115272257a;hp=7f7399100a608bec9918fab8b6080f071776d4b6;hpb=f31b7fd0769b818f910546ec97284cceb7450593;p=pintos-anon diff --git a/src/devices/intq.c b/src/devices/intq.c index 7f73991..8754c85 100644 --- a/src/devices/intq.c +++ b/src/devices/intq.c @@ -3,7 +3,6 @@ #include "threads/thread.h" static int next (int pos); -static bool owned_by_current_thread (const struct intq *); static void wait (struct intq *q, struct thread **waiter); static void signal (struct intq *q, struct thread **waiter); @@ -17,29 +16,6 @@ intq_init (struct intq *q, const char *name) q->head = q->tail = 0; } -/* Locks out other threads from Q (with Q's lock) and interrupt - handlers (by disabling interrupts). */ -void -intq_lock (struct intq *q) -{ - ASSERT (!intr_context ()); - ASSERT (!owned_by_current_thread (q)); - - lock_acquire (&q->lock); - q->old_level = intr_disable (); -} - -/* Unlocks Q. */ -void -intq_unlock (struct intq *q) -{ - ASSERT (!intr_context ()); - ASSERT (owned_by_current_thread (q)); - - lock_release (&q->lock); - intr_set_level (q->old_level); -} - /* Returns true if Q is empty, false otherwise. */ bool intq_empty (const struct intq *q) @@ -58,18 +34,22 @@ intq_full (const struct intq *q) /* Removes a byte from Q and returns it. Q must not be empty if called from an interrupt handler. - Otherwise, if Q is empty, first waits until a byte is added. - Either Q must be locked or we must be in an interrupt - handler. */ + Otherwise, if Q is empty, first sleeps until a byte is + added. */ uint8_t intq_getc (struct intq *q) { uint8_t byte; - ASSERT (owned_by_current_thread (q)); - while (intq_empty (q)) - wait (q, &q->not_empty); - + ASSERT (intr_get_level () == INTR_OFF); + while (intq_empty (q)) + { + ASSERT (!intr_context ()); + lock_acquire (&q->lock); + wait (q, &q->not_empty); + lock_release (&q->lock); + } + byte = q->buf[q->tail]; q->tail = next (q->tail); signal (q, &q->not_full); @@ -78,15 +58,19 @@ intq_getc (struct intq *q) /* Adds BYTE to the end of Q. Q must not be full if called from an interrupt handler. - Otherwise, if Q is full, first waits until a byte is removed. - Either Q must be locked or we must be in an interrupt - handler. */ + Otherwise, if Q is full, first sleeps until a byte is + removed. */ void intq_putc (struct intq *q, uint8_t byte) { - ASSERT (owned_by_current_thread (q)); + ASSERT (intr_get_level () == INTR_OFF); while (intq_full (q)) - wait (q, &q->not_full); + { + ASSERT (!intr_context ()); + lock_acquire (&q->lock); + wait (q, &q->not_full); + lock_release (&q->lock); + } q->buf[q->head] = byte; q->head = next (q->head); @@ -100,24 +84,13 @@ next (int pos) return (pos + 1) % INTQ_BUFSIZE; } -/* Returns true if Q is "owned by" the current thread; that is, - if Q is locked by the current thread or if we're in an - external interrupt handler. */ -static bool -owned_by_current_thread (const struct intq *q) -{ - return (intr_context () - || (lock_held_by_current_thread (&q->lock) - && intr_get_level () == INTR_OFF)); -} - /* WAITER must be the address of Q's not_empty or not_full member. Waits until the given condition is true. */ static void wait (struct intq *q, struct thread **waiter) { ASSERT (!intr_context ()); - ASSERT (owned_by_current_thread (q)); + ASSERT (intr_get_level () == INTR_OFF); ASSERT ((waiter == &q->not_empty && intq_empty (q)) || (waiter == &q->not_full && intq_full (q))); @@ -132,7 +105,7 @@ wait (struct intq *q, struct thread **waiter) static void signal (struct intq *q, struct thread **waiter) { - ASSERT (owned_by_current_thread (q)); + ASSERT (intr_get_level () == INTR_OFF); ASSERT ((waiter == &q->not_empty && !intq_empty (q)) || (waiter == &q->not_full && !intq_full (q)));