X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fdevices%2Fintq.c;h=40b23ae6a48fe5bd0dfd3d1ed65b9ad97c31c505;hp=7f7399100a608bec9918fab8b6080f071776d4b6;hb=500278652b3d3ec6ba08c150e749b65ca4a5d208;hpb=b2a1e970fa78d8b4c31239ff2ac9ef2b4bab09a7 diff --git a/src/devices/intq.c b/src/devices/intq.c index 7f73991..40b23ae 100644 --- a/src/devices/intq.c +++ b/src/devices/intq.c @@ -3,43 +3,18 @@ #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); -/* Initializes interrupt queue Q, naming it NAME (for debugging - purposes). */ +/* Initializes interrupt queue Q. */ void -intq_init (struct intq *q, const char *name) +intq_init (struct intq *q) { - lock_init (&q->lock, name); + lock_init (&q->lock); q->not_full = q->not_empty = NULL; 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) @@ -57,19 +32,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. */ + If Q is empty, sleeps until a byte is added. + When called from an interrupt handler, Q must not be empty. */ 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); @@ -77,16 +55,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. */ + If Q is full, sleeps until a byte is removed. + When called from an interrupt handler, Q must not be full. */ 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 +81,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) +wait (struct intq *q UNUSED, 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))); @@ -130,9 +100,9 @@ wait (struct intq *q, struct thread **waiter) thread is waiting for the condition, wakes it up and resets the waiting thread. */ static void -signal (struct intq *q, struct thread **waiter) +signal (struct intq *q UNUSED, 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)));