Path: blob/main/tools/test/stress2/testcases/shm/shm.c
39566 views
/*-1* Copyright (c) 2008 Peter Holm <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25*/2627/* Test shared memory */2829#include <sys/param.h>30#include <sys/ipc.h>31#include <sys/msg.h>32#include <sys/sem.h>33#include <sys/shm.h>34#include <err.h>35#include <errno.h>36#include <signal.h>37#include <stdio.h>38#include <stdlib.h>39#include <unistd.h>4041#include "stress.h"4243static int shmid = -1;44static key_t shmkey;45static char *shm_buf;4647static int semid = -1;48static key_t semkey;49static struct sembuf sop[2];5051static size_t pgsize;52static pid_t pid;5354int55setup(int nb __unused)56{57int seed;5859pgsize = sysconf(_SC_PAGESIZE);6061seed = getpid();62shmkey = ftok("/tmp", seed);63if ((shmid = shmget(shmkey, 10 * pgsize, IPC_CREAT | IPC_EXCL | 0640)) == -1) {64if (errno == ENOSPC) {65fprintf(stderr, "Max number of semaphores reached.\n");66exit(1);67}68err(1, "shmget (%s:%d)", __FILE__, __LINE__);69}7071shm_buf = 0;72if ((shm_buf = shmat(shmid, NULL, 0)) == (void *) -1)73err(1, "sender: shmat (%s:%d)", __FILE__, __LINE__);7475semkey = ftok("/var", seed);76if ((semid = semget(semkey, 2, IPC_CREAT | IPC_EXCL | 0640)) == -1) {77if (errno == ENOSPC) {78fprintf(stderr, "Max number of semaphores reached.\n");79exit(1);80}81err(1, "semget (%s:%d)", __FILE__, __LINE__);82}83/* Initialize the semaphore. */84sop[0].sem_num = 0;85sop[0].sem_op = 0; /* This is the number of runs without queuing. */86sop[0].sem_flg = 0;87sop[1].sem_num = 1;88sop[1].sem_op = 0; /* This is the number of runs without queuing. */89sop[1].sem_flg = 0;90if (semop(semid, sop, 2) == -1)91err(1, "init: semop (%s:%d)", __FILE__, __LINE__);92return (0);93}9495void96cleanup(void)97{98if (shmid != -1)99if (shmctl(shmid, IPC_RMID, NULL) == -1 && errno != EINVAL)100warn("shmctl IPC_RMID (%s:%d)", __FILE__, __LINE__);101if (semid != -1)102if (semctl(semid, 0, IPC_RMID, 0) == -1 && errno != EINVAL)103warn("shmctl IPC_RMID (%s:%d)", __FILE__, __LINE__);104}105106static void107Wait(int i) {108sop[0].sem_num = i;109sop[0].sem_op = -1;110if (semop(semid, sop, 1) == -1) {111if (errno != EINTR && errno != EIDRM && errno != EINVAL)112warn("Wait: semop (%s:%d)", __FILE__, __LINE__);113done_testing = 1;114}115}116117static void118Sig(int i) {119sop[0].sem_num = i;120sop[0].sem_op = 1;121if (semop(semid, sop, 1) == -1) {122if (errno != EINTR && errno != EIDRM && errno != EINVAL)123warn("Sig: semop (%s:%d)", __FILE__, __LINE__);124done_testing = 1;125}126}127128int129test(void)130{131int i = 0;132133pid = fork();134if (pid == -1) {135perror("fork");136exit(2);137}138139if (pid == 0) { /* child */140i = 0;141for (;;) {142Wait(1);143if (done_testing == 1)144break;145if (shm_buf[i] != (i % 128)) {146fprintf(stderr,147"child %d: expected %d, got %d\n",148getpid(), i % 128, shm_buf[i]);149break;150}151shm_buf[i] = 0;152i = (i + 1) % (10 * pgsize);153shm_buf[i] = (i % 128);154i = (i + 1) % (10 * pgsize);155Sig(0);156}157_exit(0);158159} else { /* parent */160i = 0;161for (;;) {162shm_buf[i] = (i % 128);163Sig(1);164i = (i + 1) % (10 * pgsize);165Wait(0);166if (done_testing == 1)167break;168if (shm_buf[i] != (i % 128)) {169fprintf(stderr,170"parent(%d): expected %d, got %d\n",171getpid(), i % 128, shm_buf[i]);172break;173}174shm_buf[i] = 0;175i = (i + 1) % (10 * pgsize);176}177kill(pid, SIGHUP);178kill(pid, SIGKILL);179}180return (0);181}182183184