Semaphore Implementation in Operating Systems: Solutions and Discussions, Exams of Operating Systems

This document from cs 414 at the university of virginia explores the implementation of semaphores in operating systems. Topics include why hardware does not implement p&v directly, the use of atomic reads and writes for mutual exclusion, and the implementation of semaphores on uniprocessors and multiprocessors. The document also discusses the use of test-and-set instructions for mutual exclusion and the importance of careful implementation and layering.

Typology: Exams

Pre 2010

Uploaded on 08/31/2009

koofers-user-bzd
koofers-user-bzd 🇺🇸

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS 414 : Operating Systems
UNIVERSITY OF VIRGINIA
Department of Computer Science
Fall 2005
Topic 6: Semaphore Implementation
Readings for this topic: Section 6.5.2
No existing hardware implements P&V directly. Why?
Need a simple way of doing mutual exclusion in order to implement P’s and V’s. We could
use atomic reads and writes, as in the ‘‘too much milk’’ problem. Any drawbacks?
Uniprocessor solution: disable interrupts.
typedef struct {
int count;
} SEMAPHORE;
P(s)
SEMAPHORE *s;
while (true) {
Disable interrupts;
if (s->count > 0) {
s->count-= 1;
Enable interrupts;
return;
}
Enable interrupts;
}
6.1
pf3
pf4
pf5

Partial preview of the text

Download Semaphore Implementation in Operating Systems: Solutions and Discussions and more Exams Operating Systems in PDF only on Docsity!

CS 414 : Operating Systems

UNIVERSITY OF VIRGINIA

Department of Computer Science

Fall 2005

Topic 6: Semaphore Implementation

Readings for this topic: Section 6.5. No existing hardware implements P&V directly. Why?

Need a simple way of doing mutual exclusion in order to implement P’s and V’s. We could

use atomic reads and writes, as in the ‘‘too much milk’’ problem. Any drawbacks?

Uniprocessor solution: disable interrupts.

typedef struct { int count; } SEMAPHORE; P(s) SEMAPHORE *s; while (true) { Disable interrupts; if (s->count > 0) { s->count-= 1; Enable interrupts; return ; } Enable interrupts; }

V(s) SEMAPHORE *s; Disable interrupts; s->count += 1; Enable interrupts;

What is wrong with this code?

Modification: add a queue of waiting processes to the semaphore. On failed P, add to queue.

On V, remove from queue.

typedef struct { int count; queue q; } SEMAPHORE;

P(s) SEMAPHORE *s; { while (true) { Disable interrupts; if (s->count > 0) { s->count-= 1; Enable interrupts; return ; } Add process to s->q Enable interrupts; Redispatch } }

Read-modify-writes may be implemented directly in memory hardware, or in the processor by

refusing to release the memory bus.

Using test and set to implement semaphores in a multiprocessor: For each semaphore, keep a

test-and-set integer in addition to the semaphore integer and the queue of waiting processes.

typedef struct { int count; queue q; int t; } SEMAPHORE;

P(s) SEMAPHORE s; { Disable interrupts; while (TAS(s->t) != 0) / do nothing */; if (s->count > 0) { s->count = s->count-1; s->t = 0; Enable interrupts; return ; } Add process to s->q; s->t = 0; Redispatch; }

V(s) SEMAPHORE s; { Disable interrupts; while (TAS(s->t) != 0) / do nothing */; if (s->q empty) { s->count += 1; } else { Remove first process from s->q; Wake it up; } s->t = 0; Enable interrupts; }

Is this solution correct?

Is it busy-waiting?

Why do we still have to disable interrupts in addition to using test and set?

What if we change the order of Disable interrupts and while (TAS (s->t) != 0)?

Important point: implement some mechanism once, very carefully. Then always write pro-

grams that use that mechanism. Layering is very important.