#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)
}
/* 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);
}
/* 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);
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)));
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)));