Semaphores and Mailboxes B. Ramamurthy 1

advertisement
Semaphores and Mailboxes
B. Ramamurthy
1
Critical sections and Semaphores
• When multiples tasks are executing there may be
sections where only one task could execute at a
given time: critical region or critical section
• There may be resources which can be accessed only
be one of the processes: critical resource
• Semaphores can be used to ensure mutual exclusion
to critical sections and critical resources
Page 2
Semaphores in exinu
•
•
#include <kernel.h>
#include <queue.h>
•
•
•
/* Semaphore state definitions */
#define SFREE 0x01 /**< this semaphore is free
#define SUSED 0x02 /**< this semaphore is used
•
•
/* type definition of "semaphore" */
typedef ulong semaphore;
•
•
•
•
•
•
•
/* Semaphore table entry */
struct sentry
{
char state;
/**< the state SFREE or SUSED
short count;
/**< count for this semaphore
queue queue;
/**< requires q.h.
};
/**< queue.h must define # of sem queues */
*/
*/
*/
*/
*/
3
Semaphores in exinu (contd.)
•
extern struct sentry semtab[];
•
•
•
•
•
•
/**
* isbadsem - check validity of reqested semaphore id and state
* @param s id number to test; NSEM is declared to be 100 in kernel.h
A system typically has a predetermined limited number of semaphores
*/
#define isbadsem(s) (((ushort)(s) >= NSEM) || (SFREE == semtab[s].state))
•
•
•
•
•
•
•
/* Semaphore function declarations */
syscall wait(semaphore);
syscall signal(semaphore);
syscall signaln(semaphore, short);
semaphore newsem(short);
syscall freesem(semaphore);
syscall scount(semaphore);
4
Definition of Semaphores functions
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
static semaphore allocsem(void);
/**
* newsem - allocate and initialize a new semaphore.
* @param count - number of resources available without waiting.
* example: count = 1 for mutual exclusion lock
* @return new semaphore id on success, SYSERR on failure
*/
semaphore newsem(short count)
{
irqmask ps;
semaphore sem;
ps = disable();
/* disable interrupts */
sem = allocsem();
/* request new semaphore */
if ( sem != SYSERR && count >= 0 ) /* safety check
*/
{
semtab[sem].count = count; /* initialize count */
restore(ps);
/* restore interrupts */
return sem;
/* return semaphore id */
}
restore(ps);
}
5
Semaphore: newsem contd.
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/**
* allocsem - allocate an unused semaphore and return its index.
* Scan the global semaphore table for a free entry, mark the entry
* used, and return the new semaphore
* @return available semaphore id on success, SYSERR on failure
*/
static semaphore allocsem(void)
{
int i = 0;
while(i < NSEM)
/* loop through semaphore table */
{
/* to find SFREE semaphore */
if( semtab[i].state == SFREE )
{
semtab[i].state = SUSED;
return i;
}
i++;
}
return SYSERR; }
6
Semaphore: wait(…)
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/**
* wait - make current process wait on a semaphore
* @param sem semaphore for which to wait
* @return OK on success, SYSERR on failure
*/
syscall wait(semaphore sem)
{
irqmask ps;
struct sentry *psem;
pcb *ppcb;
ps = disable();
/* disable interrupts
*/
if ( isbadsem(sem) )
/* safety check
*/
{
restore(ps);
return SYSERR;
}
ppcb = &proctab[currpid]; /* retrieve pcb from process table */
psem = &semtab[sem];
/* retrieve semaphore entry
*/
if( --(psem->count) < 0 ) /* if requested resource is unavailable */
{
ppcb->state = PRWAIT; /* set process state to PRWAIT*/
7
Semaphore: wait()
•
•
•
•
•
•
•
ppcb->sem = sem; /* record semaphore id in pcb */
enqueue(currpid, psem->queue);
resched();
/* place in wait queue and reschedule */
}
restore(ps);
/* restore interrupts
*/
return OK;
}
8
Semaphore: signal()
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/*signal - signal a semaphore, releasing one waiting process, and block
* @param sem id of semaphore to signal
* @return OK on success, SYSERR on failure
*/
syscall signal(semaphore sem)
{
irqmask ps;
register struct sentry *psem;
ps = disable();
/* disable interrupts
*/
if ( isbadsem(sem) )
/* safety check
*/
{
restore(ps);
return SYSERR;
}
psem = &semtab[sem];
/* retrieve semaphore entry
*/
if ( (psem->count++) < 0 ) /* release one process from wait queue */
{ ready(dequeue(psem->queue), RESCHED_YES); }
restore(ps);
/* restore interrupts
*/
return OK;
}
9
Semaphore: usage
• Problem 1:
– Create 3 tasks that each sleep for a random time and
update a counter.
– Counter is the critical resources shared among the
processes.
– Only one task can update the counter at a time so that
counter value is correct.
• Problem 2:
– Create 3 tasks; task 1 updates the counter by 1 and
then signal task 2 that updates the counter by 2 and
then signals task 3 to update the counter by 3.
10
Problem 1
#include <..>
//declare semaphore
semaphore mutex1 = newsem(1);
int counter = 0;
//declare functions: proc1,proc1, proc3
ready(create((void *)proc1, INITSTK, INITPRIO, “PROC1",,
2, 0, NULL), RESCHED_NO);
ready(create((void *)proc2, INITSTK, INITPRIO, “PROC2",,
2, 0, NULL), RESCHED_NO);
ready(create((void *)proc3, INITSTK, INITPRIO, “PROC3",,
2, 0, NULL), RESCHED_NO);
11
Problem 1: multi-tasks
void proc1()
{ while (1) {
sleep (rand()%10);
wait(mutex1);
counter++;
signal(mutex1);
}}
void proc2()
{ while (1) {
sleep (rand()%10);
wait(mutex1);
counter++;
signal(mutex1);
}}
//similarly proc3
Simulation of this;
12
Problem 1
Task 1
Counter1
Task 2
Task 3
13
Problem 2
semaphore synch12 = newsem(0);
semaphore synch23 = newsem(0);
semaphore synch31 = newsem(0);
ready(create((void *)proc1, INITSTK, INITPRIO,
“PROC1",, 2, 0, NULL), RESCHED_NO);
ready(create((void *)proc2, INITSTK, INITPRIO,
“PROC2",, 2, 0, NULL), RESCHED_NO);
ready(create((void *)proc3, INITSTK, INITPRIO,
“PROC3",, 2, 0, NULL), RESCHED_NO);
signal(synch31);
14
Task flow
void proc1()
void proc2()
void proc3()
•{
•while (1) {
•sleep (rand()%10);
•wait(synch31);
•counter++;
•signal(synch12);
•} }
•{
•while (1) {
•sleep (rand()%10);
•wait(synch12);
•counter++;
•signal(synch23);
•} }
•{
•while (1) {
•sleep(rand()%10);
•wait(synch23);
•counter++;
•signal(synch31); } }
15
UART and UART Drivers
Inside the
system
UART Driver
Outside
Actual UART
Buffer
(input, output)
Registers
(Control, status)
16
Reverse Engineer UART read, write and
intr (interrupt)
Application
: UARTRead
: UARTIntr
: UARTWrite
: UART
read(buf , 4)
wait(isem)
read bit by bit
signal(isem)
copy ibuf to application
17
UART Operation and code (contd.)
• We will look at the sequence diagrams for
other UART operations and read the code.
• Lets look at initialize.c
18
Download