100% found this document useful (3 votes)
195 views

Semaphore

The document describes how wait() and signal() system calls work with semaphores to synchronize processes. Process X creates two semaphores, consumed and produced. Process P and C then loop, with P waiting on consumed and signaling produced, while C does the opposite, waiting on produced and signaling consumed. This allows the processes to synchronize and prevents C from printing n values until P has incremented n through its loop.

Uploaded by

api-27287218
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
195 views

Semaphore

The document describes how wait() and signal() system calls work with semaphores to synchronize processes. Process X creates two semaphores, consumed and produced. Process P and C then loop, with P waiting on consumed and signaling produced, while C does the opposite, waiting on produced and signaling consumed. This allows the processes to synchronize and prevents C from printing n values until P has incremented n through its loop.

Uploaded by

api-27287218
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

How wait( ) and signal( ) calls work

Process X Process P Process C


consumed = screate(0); for (i=1; i <=2000; i++) { for (i=1; i <=2000; i++) {
produced = screate(1); wait(consumed); wait(produced);
resume(create(.., P,..)); n++; printf(“n = %d\n”, n);
resume(create(..,C,..)); signal(produced);} signal(consumed);}

struct sentry { screate(count)


char sstate; 1. sem = newsem( ); gets an unused entry.
short semcnt; 2. semaph[sem].semcnt = count;
short sqhead;
short sqtail; newsem( )
}; if (semaph[sem].sstate == SFREE) {
semaph[sem]sstate = SUSED;
extern struct sentry semaph[] return(sem);

Scenario: Process P executes before Process C

Process P Process C
wait(consumed) signal(consumed)
disable(ps); interrupts are disabled disable(ps); interrupts are disabled
sptr = &semaph[sem]; sptr = &semaph[sem];
if (--sptr->semcnt < 0 ) { if (sptr->semcnt++ < 0 ) {
(pptr = &proctab[currpid])->pstate = PRWAIT; ready(getfirst (sptr->sqhead));
pptr->psem = sem; resched( ); }
enquue(currpid, sptr->sqtail); restore(ps); interrupts are enabled
resched( ); } return;
restore(ps); interrupts are enabled
return;
/* sem.h - isbadsem */

#ifndef NSEM
#define NSEM 45 /* number of semaphores, if not defined */
#endif

#define SFREE '\01' /* this semaphore is free */


#define SUSED '\02' /* this semaphore is used */

struct sentry { /* semaphore table entry */


char sstate; /* the state SFREE or SUSED */
int semcnt; /* count for this semaphore */
int sqhead; /* q index of head of list */
int sqtail; /* q index of tail of list */
};
extern struct sentry semaph[];
extern int nextsem;

#define isbadsem(s) (s<0 || s>=NSEM)

/* screate.c - screate, newsem */

#include "conf.h"
#include "kernel.h"
#include "proc.h"
#include "q.h"
#include "sem.h"

/*------------------------------------------------------------------------*/
/* newsem -- allocate an unused semaphore and return its index */
/*------------------------------------------------------------------------*/

int newsem(void)
{
int sem;
int i;

for (i=0 ; i<NSEM ; i++) {


sem=nextsem--;
if (nextsem < 0)
nextsem = NSEM-1;
if (semaph[sem].sstate==SFREE) {
semaph[sem].sstate = SUSED;
return(sem);
}
}
return(SYSERR);
}
/*------------------------------------------------------------------------*/
/* screate -- create and initialize a semaphore, returning its id */
/*------------------------------------------------------------------------*/

SYSCALL screate(int count) /* initial count (>=0) */


{
int ps;
int sem;

ps = disable();
if ( count<0 || (sem=newsem())==SYSERR ) {
restore(ps);
return(SYSERR);
}
semaph[sem].semcnt = count;
/* sqhead and sqtail were initialized at system startup */
restore(ps);
return(sem);
}

/*------------------------------------------------------------------------
* sdelete -- delete a semaphore by releasing its table entry
*------------------------------------------------------------------------
*/
SYSCALL sdelete(int sem)
{
short ps;
int pid;
struct sentry *sptr; /* address of sem to free */

ps = disable();
if (isbadsem(sem) || semaph[sem].sstate==SFREE) {
restore(ps);
return(SYSERR);
}
sptr = &semaph[sem];
sptr->sstate = SFREE;
if (nonempty(sptr->sqhead)) { /* free waiting processes */
while( (pid=getfirst(sptr->sqhead)) != EMPTY)
ready(pid,RESCHNO);
resched();
}
restore(ps);
return(OK);
}
/*------------------------------------------------------------------------*/
/* signal -- signal a semaphore, releasing one waiting process */
/*------------------------------------------------------------------------*/

SYSCALL signal(int sem)


{
struct sentry *sptr;
int ps;

ps = disable();
if (isbadsem(sem) || (sptr= &semaph[sem])->sstate==SFREE) {
restore(ps);
return(SYSERR);
}
if ((sptr->semcnt++) < 0)
ready(getfirst(sptr->sqhead), RESCHYES);
restore(ps);
return(OK);
}

/*------------------------------------------------------------------------*/
/* wait -- make current process wait on a semaphore */
/*------------------------------------------------------------------------*/

SYSCALL wait(int sem)


{
int ps;
struct sentry *sptr;
struct pentry *pptr;

ps = disable();
if (isbadsem(sem) || (sptr= &semaph[sem])->sstate==SFREE) {
restore(ps);
return(SYSERR);
}
if (--(sptr->semcnt) < 0) {
(pptr = &proctab[currpid])->pstate = PRWAIT;
pptr->psem = sem;
enqueue(currpid,sptr->sqtail);
resched();
}
restore(ps);
return(OK);
}

You might also like