Xinu Semaphores Resources Critical Resources 1112020 Shared resources

  • Slides: 17
Download presentation
Xinu Semaphores

Xinu Semaphores

Resources & Critical Resources • • • 11/1/2020 Shared resources: need mutual exclusion Tasks

Resources & Critical Resources • • • 11/1/2020 Shared resources: need mutual exclusion Tasks cooperating to complete a job Tasks contending to access a resource Tasks synchronizing Critical resources and critical region A important synchronization and mutual exclusion primitive / resource is “semaphore” Page 2

Critical sections and Semaphores • When multiples tasks are executing there may be sections

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 11/1/2020 Page 3

Semaphores See semaphore. h of xinu 11/1/2020 Page 4

Semaphores See semaphore. h of xinu 11/1/2020 Page 4

Semaphores in exinu • • #include <kernel. h> #include <queue. h> • • •

Semaphores in exinu • • #include <kernel. h> #include <queue. h> • • • /* Semaphore state definitions */ #define SFREE 0 x 01 /**< this semaphore is free #define SUSED 0 x 02 /**< 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; /**< requires q. h. */ }; /**< queue. h must define # of sem queues */ */ */ 5

Semaphores in exinu (contd. ) • extern struct sentry semtab[]; • • • /**

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 signaln(semaphore, short); semaphore newsem(short); syscall freesem(semaphore); syscall scount(semaphore); 6

Definition of Semaphores functions • • • • • • static semaphore allocsem(void); /**

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); } 7

Semaphore: newsem contd. • • • • • /** * allocsem - allocate an

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; } 8

Semaphore: wait(…) • • • • • • /** * wait - make current

Semaphore: wait(…) • • • • • • /** * wait - make current process wait on a semaphore * @param 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*/ 9

Semaphore: wait() • • ppcb->sem = sem; /* record semaphore id in pcb */

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; } 10

Semaphore: signal() • • • • • /*signal - signal a semaphore, releasing one

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; 11

Semaphore: usage • Problem 1: – Create 3 tasks that each sleep for a

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. 12

Problem 1 #include <. . > //declare semaphore mutex 1 = newsem(1); int counter

Problem 1 #include <. . > //declare semaphore mutex 1 = newsem(1); int counter = 0; //declare functions: proc 1, proc 3 ready(create((void *)proc 1, INITSTK, INITPRIO, “PROC 1", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 2, INITSTK, INITPRIO, “PROC 2", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 3, INITSTK, INITPRIO, “PROC 3", , 2, 0, NULL), RESCHED_NO); 13

Problem 1: multi-tasks void proc 1() { while (1) { sleep (rand()%10); wait(mutex 1);

Problem 1: multi-tasks void proc 1() { while (1) { sleep (rand()%10); wait(mutex 1); counter++; signal(mutex 1); }} void proc 2() { while (1) { sleep (rand()%10); wait(mutex 1); counter++; signal(mutex 1); }} //similarly proc 3 14

Problem 1 Task 1 Counter 1 Task 2 Task 3 15

Problem 1 Task 1 Counter 1 Task 2 Task 3 15

Problem 2 semaphore synch 12 = newsem(0); semaphore synch 23 = newsem(0); semaphore synch

Problem 2 semaphore synch 12 = newsem(0); semaphore synch 23 = newsem(0); semaphore synch 31 = newsem(0); ready(create((void *)proc 1, INITSTK, INITPRIO, “PROC 1", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 2, INITSTK, INITPRIO, “PROC 2", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 3, INITSTK, INITPRIO, “PROC 3", , 2, 0, NULL), RESCHED_NO); signal(synch 31); 16

Task flow void proc 1() void proc 2() void proc 3() • { •

Task flow void proc 1() void proc 2() void proc 3() • { • while (1) { • sleep (rand()%10); • wait(synch 31); • counter++; • signal(synch 12); • } } • { • while (1) { • sleep (rand()%10); • wait(synch 12); • counter++; • signal(synch 23); • } } • { • while (1) { • sleep(rand()%10); • wait(synch 23); • counter++; • signal(synch 31); } } 17