Sweden-Number/ipc/shm_semaph_test.c

128 lines
2.7 KiB
C

/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_semaph_test.c
* Purpose: Test semaphores handleingr shared memory operations.
***************************************************************************
*/
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "shm_semaph.h"
#include <sys/shm.h>
#define DEBUG_DEFINE_VARIABLES
#include <debug.h>
static volatile int * volatile data;
static int isparent=0;
#define DELAY (rand()%10)
shm_sem sem;
static void read_write(int num)
{
int i,j ;
volatile float dummy=0;
int val;
srand(num+time(NULL));
for (i=0x3fff;i>=0;i--) {
if((i&0x7ff)==0 && isparent)
fprintf(stderr,"0x%06x\r",i);
shm_write_wait(sem);
*data= num;
for (j=DELAY ; j>=0;j--)
dummy*=2;
if (*data!=num) {
fprintf(stderr,"\nbad shm_write_wait(), num=%d\n",num);
shm_write_signal(sem);
return;
}
shm_write_signal(sem);
for (j=DELAY ; j>=0 ;j--)
dummy*=2;
shm_read_wait(sem);
val=*data;
for (j=DELAY; j>=0 ;j--)
dummy*=0.5;
if (*data!=val) {
fprintf(stderr,"\nbad shm_read_wait(), num=%d,val=%d,*data=%d\n",
num,val,*data);
shm_read_signal(sem);
return;
}
shm_read_signal(sem);
}
if (isparent)
fputc('\n',stderr);
}
static void child1()
{
read_write(2);
}
static void child2()
{
read_write(10);
}
static void parent()
{
isparent=1;
read_write(60);
}
int main()
{
int shmid;
int ret1, ret2;
int pid1, pid2;
int stat=0;
shm_sem_init(&sem);
shmid=shmget(IPC_PRIVATE, 0x100, IPC_CREAT | 0700);
data= (int *)shmat ( shmid, NULL, 0);
*data=0;
switch (pid1=fork()) {
case -1:
perror("fork 1");
return 1;
case 0:
fprintf(stderr,"child1\n");
child1();
fprintf(stderr,"child1 done\n");
return 0;
default :
}
switch (pid2=fork()) {
case -1:
perror("fork 2");
stat|=1;
break;
case 0:
fprintf(stderr,"child2\n");
child2();
fprintf(stderr,"child2 done\n");
return 0;
default :
}
fprintf(stderr,"parent\n");
if (pid2>0) { /* if second fork did not fail */
parent();
fprintf(stderr,"parent done, waiting for child2\n");
waitpid(pid2,&ret2,WUNTRACED);
stat|=ret2;
}
fprintf(stderr,"parent done, waiting for child1\n");
waitpid(pid1,&ret1,WUNTRACED);
stat|=ret1;
fprintf(stderr,"all done\n");
shmctl(shmid, IPC_RMID,NULL);
shm_sem_done(&sem);
return stat;
}