128 lines
2.7 KiB
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;
|
|
}
|