+ All Categories
Home > Business > Preparation for mit ose lab4

Preparation for mit ose lab4

Date post: 18-Nov-2014
Category:
Upload: benux-wei
View: 575 times
Download: 0 times
Share this document with a friend
Description:
Notes from MIT OSE Lab4
21
Preparation for MIT-OSE Lab4 Ben 2012/05/29
Transcript
Page 1: Preparation for mit ose lab4

Preparation for

MIT-OSE Lab4Ben

2012/05/29

Page 2: Preparation for mit ose lab4

● Locking● Scheduling

● Coordination and processes

Page 3: Preparation for mit ose lab4

● Locking● Scheduling● Coordination and processes

Page 4: Preparation for mit ose lab4

Abstract SMP architecture

● processors with one shared memory ● devices ● interrupts processed in parallel

Page 5: Preparation for mit ose lab4

Avoiding list race

insert(int data){ List *l = new List; l->data = data;

l->next = list ; // A list = l; // B

}

Lock list_lock; // one per list

insert(int data){ List *l = new List; l->data = data;

acquire(&list_lock);

l->next = list ; // A list = l; // B

release(&list_lock);}

● multiple processes adding to the disk queue

critical section, or atomic section

Page 6: Preparation for mit ose lab4

Race Condition

TimeA

A B

BCPU1

CPU2

Memoryl->next

l->next

list

list

Page 7: Preparation for mit ose lab4

Implementing lock and release

● use atomic instructions (e.g., xchg)For example, the x86 <tt>xchg %eax, addr</tt> instructiondoes the following: freeze other CPUs' memory activity for address addrtemp := *addr*addr := %eax%eax = tempun-freeze other memory activity

Page 8: Preparation for mit ose lab4

x86 asm to implement a spinlocklock: ; The lock variable. 1 = locked, 0 = unlocked. dd 0 spin_lock: mov eax, 1 xchg eax, [lock] ; Atomically swap EAX register with lock variable. test eax, eax jnz spin_lock ret spin_unlock: mov eax, 0 ; Set the EAX register to 0. xchg eax, [lock] ; Atomically swap EAX register with lock variable. ret ; The lock has been released.

Page 9: Preparation for mit ose lab4

Design Issues - locks and interrupts

● ide disk generates interrupt when disk operation completes

● interrupt causes ideintr to run● ideintr acquires lock?

deadlock? give interrupt handler lock? (recursive locks)

● xv6: critical sections have no interrupts turned on

Page 10: Preparation for mit ose lab4

Design Issues - locks and modularity

move(l1, l2) {

e = del(l1) insert(l2, e)

}

move(l1, l2) { acquire(l1.lock); acquire(l2.lock); e = del(l1) insert(l2, e) release(l1.lock) release(l2.lock) }

● recursive locks are a bad ideaideintr should certainly not use that instead of disabling interrupts!

move(l1, l2) { acquire(l1.lock); e = del(l1) release(l1.lock) acquire(l2.lock); insert(l2, e) release(l2.lock) }

Modifiedrecursiveoriginal

Page 11: Preparation for mit ose lab4

● Locking● Scheduling● Coordination and processes

Page 12: Preparation for mit ose lab4

Goals for solution

● Switching transparent to user threads● User thread cannot hog a processor

Page 13: Preparation for mit ose lab4

Code - Concurrency

- plock held across switch; why? yield: p is set runnable, p must complete switch before another scheduler chooses p

- hard to reason about; coroutine style helps

- can two schedulers select the same runnable process? - why does scheduler release after loop, and re-acquire it immediately? (run with interrupts!)

Page 14: Preparation for mit ose lab4

Code - Thread clean up

● let's look at kill: can we clean up killed process? (no: it might be running, holding locks etc.) before returning to user space: process kills itself by calling exit

● let's look at exit; can thread delete its stack?

(no: it has to switch off it!)

● wait() does the cleanup

Page 15: Preparation for mit ose lab4

● Locking● Scheduling● Coordination and processes

Required reading: remainder of proc.c, sys_wait, sys_exit, and sys_kill.

Page 16: Preparation for mit ose lab4

Coordination and more processes

Page 17: Preparation for mit ose lab4

Big picture

Multiple threads executing in the kernel and sharing memory, devices and various data structures. ● Allow more than one process to be

executing to take advantage of multiple CPUs

● Allow system calls that block waiting for I/O.

Page 18: Preparation for mit ose lab4

producer consumer queuestruct pcq { void *ptr;};

void*pcqread(struct pcq *q){

while((p=q->ptr)==0); q->ptr = 0; return p;}

pcqwrite(struct pcq *q, void *p){ while(q->ptr != 0); q->ptr = p;}

Need lock for pcq->ptr if multiple processors

Waste CPU Time. Instead of polling,Use event-based (sleep and wakeup)

Page 19: Preparation for mit ose lab4

Sleep & wakeupsleep(chan): curproc->chan = chan curproc->state = SLEEPING sched()

wakeup(chan): foreach p in proc[]: if p->chan == chan and p->state==SLEEPING: p->state = RUNNABLE

sleep(void *chan, struct spinlock *lk){ struct proc *p = curproc[cpu()]; p->chan = chan; p->state = SLEEPING; release(lk); sched(); acquire(lk);}

wakeup(void *chan){ for(each proc p) { if(p->state == SLEEPING

&& p->chan == chan) p->state = RUNNABLE; }}

Page 20: Preparation for mit ose lab4

producer consumer queue (cont.)struct pcq { void *ptr;};

void*pcqread(struct pcq *q){

while((p=q->ptr)==0); q->ptr = 0; return p;}

pcqwrite(struct pcq *q, void *p){ while(q->ptr != 0); q->ptr = p;}

struct pcq { void *ptr; struct spinlock lock; };

void* pcqread(struct pcq *q) { acquire(&q->lock); while(q->ptr == 0)sleep(q, &q->lock); p = q->ptr; q->ptr = 0; wakeup(q); /* wake pcqwrite */ release(&q->lock); return p;}pcqwrite(struct pcq *q, void *p) { acquire(&q->lock); while(q->ptr != 0) sleep(q, &q->lock); q->ptr = p; wakeup(q); /* wake pcqread */ release(&q->lock); return p;}

Page 21: Preparation for mit ose lab4

Q & A

LockingSchduling

Threads

?


Recommended