Docstoc

Semaphores and Mailboxes

Document Sample
Semaphores and Mailboxes Powered By Docstoc
					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>    /**< queue.h must define # of sem queues */

•   /* 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.            */
•   };




                                                                        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++;
•         }
                                                                              6
•         return SYSERR; }
                    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) {            •while (1) {          •while (1) {
•sleep (rand()%10);     •sleep (rand()%10);   •sleep(rand()%10);
•wait(synch31);         •wait(synch12);       •wait(synch23);
•counter++;             •counter++;           •counter++;
•signal(synch12);       •signal(synch23);     •signal(synch31); } }
•} }                    •} }




                                                                      15
    UART and UART Drivers

                                   Inside the
                                   system       Outside



UART Driver       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

				
DOCUMENT INFO