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