sema.c

text/plain

Filename: sema.c
Type: text/plain
Part: 0
Message: Re: Latch implementation

#include <sys/file.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>

int nIter = 1000000;

#define LATCH_TIMEOUT 50000000L

#include "latch.h"
#include "unix_latch.c"
int selfLatch, otherLatch;

Latch *latchArray;

#ifdef LINUX_SEM
int semId = -1;
#endif

void DoWork(int selfLatch);

void
sigusr1handler(int n)
{
   DEBUG("sigusr handler\n");
   latch_sigusr1_handler();
}


main()
{
   int child;
   int i;
   int shmid;

   for (i = 0; i < 1000; i++) {
      shmid = shmget(6500 + i, sizeof(Latch) * 2, IPC_CREAT | IPC_EXCL|0x1ff);
      if (shmid < 0) {
         DEBUG("shmget error %d %d\n", shmid, errno);
         if (i == 999) { 
            printf("Can't get shm, aborting test\n");
            exit (1); 
         }
      } else {
         break;
      }
   }
   latchArray = shmat(shmid, NULL, 0);
   if ((long)latchArray < 0) {
      printf("shmat error %ld %d\n", (long)latchArray, errno);
      exit(1);
   }
   InitSharedLatch(&latchArray[0]);
   InitSharedLatch(&latchArray[1]);
   child = fork();
   if (child < 0) {
      printf("fork error %d %d\n", child, errno);
      exit(1);
   }
   MyProcPid = getpid();
   signal(SIGUSR1, sigusr1handler);
   DoWork(child != 0);
}

static int
WaitForOther(int latch)
{
   int ret;
   Latch *l = &latchArray[latch];
   DEBUG("Wait %p\n", l);
   ret = WaitLatch(l, LATCH_TIMEOUT);
   ResetLatch(l);
   return ret;
}

static void
SignalOther(int latch)
{
   Latch *l = &latchArray[latch];
   DEBUG("Signal %p\n", l);
   SetLatch(l);
}

void 
DoWork(int l)
{
   int i;
   struct timeval tv1, tv2;
   struct timezone tz;
   float diff;

   selfLatch = l, otherLatch = selfLatch ^ 1;
   Latch *self = &latchArray[selfLatch];
   Latch *other = &latchArray[otherLatch ^ 1];
   OwnLatch(self);
   sleep(2); /* Cheat: pseudo-barrier. */
   printf("Start Test:");
#if defined(LINUX_SEM)
   printf("Using semaphores\n");
#elif defined(PIPE)
   printf("Using pipe\n");
#else
   printf("Using signal\n");
#endif
   /* Set one of the latches in the beginning. */
   if (selfLatch == 0) {
      SignalOther(otherLatch);
   }

   gettimeofday(&tv1, &tz);
   for (i = 0; i < nIter; i++) {
      if (WaitForOther(selfLatch) != 1) { 
         printf("BUG BUG BUG\n");
         exit(1);
      }
      SignalOther(otherLatch);
   }
   gettimeofday(&tv2, &tz);
   diff = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec);
   printf("%ld iterations took %.2f sec (%.2f usec/iter)\n",
          nIter, diff/1000000, diff/nIter);
}