CS111 Scribe notes for lecture on 11/1/05
Authors: Mark Gin, Ka Leung
Wait-free data structures
- Use atomic instructions (like compare_and_swap), so there is no race conditions or deadlock (since it never needs locking).
- No locking overhead, which yields better performance.
- Avoid concurrency issues by design
- Difficult to design (possibly more complex).
- May not always be possible due to limitations.
Wait-free queues coding example:
queue_t *queue_init(int capacity)
{
queue_t *q = malloc(sizeof(queue_t));
q->queue = malloc(sizeof(queuedata_t) * (capacity+1));
q->head = 0;
q->tail = 0;
q->capacity = capacity;
return q;
}
void queue_enq(queue_t *q, queuedata_t data)
{
while( (q->tail+1) % (q->capacity+1) == q->head )
yield();
q->queue[q->tail] = data;
q->tail = (q->tail+1) % (q->capacity+1);
}
queuedata_t queue_deq(queue_t *q)
{
queuedata_t data;
while(q->head == q->tail)
yield();
data = q->queue[q->head];
q->head = (q->head+1) % (q->capacity+1);
return data;
}
Note that there is no critical section in the code. Also, there is a limit of only one reader and one writer at a time for this to work.
How does I/O interface work inside the kernel?
- Input / Output is an interface to hardware, such as: disks, network devices, printers, displays.
è “Code bloat” occurs if each interface has to know how to talk to every type of disk.
- Alternative: use a multi-layer interface
- Device driver is software in kernel that communicates with the device controllers to send commands and read results.
- Goals:
· Throughput, number of request per second the device can handle
· Latency, time it takes to respond to any request
- Factors affecting them:
· Overhead – How much costs to communicate with a device
· Functionality – What device can handle
Costs of machine operations (example)
Cycle = 10^(-9)s
Programmed IO 10^(-6)s or 10000 cycles
Let’s read 40 bytes from a device:
Simples and oldest interaction mechanism is Programmed IO
Special Instructions to read/write to devices (not memory)
on x86: inb, outb, inw, outw
Controller Registers
*status register indicates if disk is done
while (inb(status) != 0)
//yield
result = inb(result);
outb(data1, 0);
outb(data2, 0);
outb(data3, 0);
outb(data4, 0);
outb(command, 32);
The costs of Programmed IO is very expensive: uses BUS, synchronization and lock issues
To read 40 bytes from a disk
1) Write command: 5 PIO Instructions
2) Wait for command to complete 50 microseconds to complete
3) Read results: 40 PIO
Overhead: 95 microseconds
Latency: 95 microseconds (busy waiting)
Throughput: 10500/s (inverse of overhead)