Move serial interrupt queue into new file intq.c.
[pintos-anon] / src / devices / intq.h
1 #ifndef DEVICES_INTQ_H
2 #define DEVICES_INTQ_H
3
4 #include "threads/interrupt.h"
5 #include "threads/synch.h"
6
7 /* An "interrupt queue", a circular buffer shared between
8    kernel threads and external interrupt handlers.
9
10    A kernel thread that touches an interrupt queue must bracket
11    its accesses with calls to intq_lock() and intq_unlock().
12    These functions take a lock associated with the queue (which
13    locks out other kernel threads) and disable interrupts (which
14    locks out interrupt handlers).
15
16    An external interrupt handler that touches an interrupt queue
17    need not take any special precautions.  Interrupts are
18    disabled in an external interrupt handler, so other code will
19    not interfere.  The interrupt cannot occur during an update to
20    the interrupt queue by a kernel thread because kernel threads
21    disable interrupts while touching interrupt queues.
22
23    Incidentally, this has the structure of a "monitor".  Normally
24    we'd use locks and condition variables from threads/synch.h to
25    implement a monitor.  Unfortunately, those are intended only
26    to protect kernel threads from one another, not from interrupt
27    handlers. */
28
29 /* Queue buffer size, in bytes. */
30 #define INTQ_BUFSIZE 8
31
32 /* A circular queue of bytes. */
33 struct intq
34   {
35     /* Mutual exclusion. */
36     enum intr_level old_level;  /* Excludes interrupt handlers. */
37     struct lock lock;           /* Excludes kernel threads. */
38
39     /* Waiting threads. */
40     struct thread *not_full;    /* Thread waiting for not-full condition. */
41     struct thread *not_empty;   /* Thread waiting for not-empty condition. */
42
43     /* Queue. */
44     uint8_t buf[INTQ_BUFSIZE];  /* Buffer. */
45     int head;                   /* New data is written here. */
46     int tail;                   /* Old data is read here. */
47   };
48
49 void intq_init (struct intq *, const char *);
50 void intq_lock (struct intq *);
51 void intq_unlock (struct intq *);
52 bool intq_empty (const struct intq *);
53 bool intq_full (const struct intq *);
54 uint8_t intq_getc (struct intq *);
55 void intq_putc (struct intq *, uint8_t);
56
57 #endif /* devices/intq.h */