Tom Kelliher, CS42
Sept. 6, 1996
Block Diagram of a Computer System:
How does the CPU manage all these resources?
What are their relative speeds?
Consider reading a sector from a disk:
typedef struct { short busy; short status; short command; ... } disk;
Kernel level routine for reading disk block:
int ReadBlock (disk d, char* buffer, int blockNum) { while (d.busy) /* Verify idle */ ; /* Send read command to disk. */ while (d.busy) /* Busy wait on read */ ; return d.status; }
Used at low-level by scanf().
OS operates on user's behalf --- user doesn't directly manipulate hardware.
How efficient is this?
Kernel level routine for reading disk block:
int ReadBlock (disk d, char* buffer, int blockNum) { while (d.busy) /* Verify idle */ /* Go do something else and check back. */ /* Send read command to disk. */ while (d.busy) /* Go do something else and check back. */ return d.status; }
How safe is this?
Introduce parallelism into system by decoupling CPU and I/O devices.
Schema:
Interrupt Features:
CPU instruction cycle:
do { fetch instruction; increment pc; decode instruction; execute instruction; if (interrupt) { push pc; pc = loc(handler); } } while (forever);
Global declarations:
#define FALSE 0 #define TRUE 1
kernel area:
int busy; /* local flag of channel (I/O device) status */
User data area:
#define MAXBUF 5 buffer buf[MAXBUF]; int nextget = 0; /* index of next full buffer */ int nextio = 0; /* index of next buffer to fill */ int free = MAXBUF; /* number of free buffers */
System calls:
int getbuf() { int current; while (free == MAXBUF) /* Call CPU scheduler. */ current = nextget; nextget = ++nextget % MAXBUF; return (current); } relbuf() { free++; if (!busy) { busy = TRUE; startread(buf[nextio]); } }
user code:
USER() { int cur; busy = TRUE; startread(buf[nextio]); do { cur = getbuf(); /* Use buf[cur]. */> relbuf(); /* Compute. */ } while (!done); }
Interrupt handler called when interrupt received from channel ( independent process):
int_hndl() { /* Save processor state. */ busy = FALSE; nextio = ++nextio % MAXBUF; free--; if (free > 0) { busy = TRUE; startread(buf[nextio]); } /* Restore processor state. */ }
Interrupt driven OS called:
DMA.
A block I/O device could swamp a CPU.
Solution: Let device access memory itself.
Here's what's going on with DMA:
Memory arbitration problems here.