sema.c
text/plain
#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);
}