1f08c3bdfSopenharmony_ci/******************************************************************************/ 2f08c3bdfSopenharmony_ci/* */ 3f08c3bdfSopenharmony_ci/* Copyright (c) International Business Machines Corp., 2001 */ 4f08c3bdfSopenharmony_ci/* */ 5f08c3bdfSopenharmony_ci/* This program is free software; you can redistribute it and/or modify */ 6f08c3bdfSopenharmony_ci/* it under the terms of the GNU General Public License as published by */ 7f08c3bdfSopenharmony_ci/* the Free Software Foundation; either version 2 of the License, or */ 8f08c3bdfSopenharmony_ci/* (at your option) any later version. */ 9f08c3bdfSopenharmony_ci/* */ 10f08c3bdfSopenharmony_ci/* This program is distributed in the hope that it will be useful, */ 11f08c3bdfSopenharmony_ci/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 12f08c3bdfSopenharmony_ci/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 13f08c3bdfSopenharmony_ci/* the GNU General Public License for more details. */ 14f08c3bdfSopenharmony_ci/* */ 15f08c3bdfSopenharmony_ci/* You should have received a copy of the GNU General Public License */ 16f08c3bdfSopenharmony_ci/* along with this program; if not, write to the Free Software */ 17f08c3bdfSopenharmony_ci/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 18f08c3bdfSopenharmony_ci/* */ 19f08c3bdfSopenharmony_ci/******************************************************************************/ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci/******************************************************************************/ 22f08c3bdfSopenharmony_ci/* */ 23f08c3bdfSopenharmony_ci/* History: Nov - 21 - 2001 Created - Manoj Iyer, IBM Austin TX. */ 24f08c3bdfSopenharmony_ci/* email:manjo@austin.ibm.com */ 25f08c3bdfSopenharmony_ci/* */ 26f08c3bdfSopenharmony_ci/* Nov - 26 - 2001 Modified - Manoj Iyer, IBM Austin Tx. */ 27f08c3bdfSopenharmony_ci/* - Added function rm_shared_mem. */ 28f08c3bdfSopenharmony_ci/* */ 29f08c3bdfSopenharmony_ci/* Dec - 03 - 2001 Modified - Manoj Iyer, IBM Austin Tx. */ 30f08c3bdfSopenharmony_ci/* - Added code to spawn threads. */ 31f08c3bdfSopenharmony_ci/* - Removed dead code. */ 32f08c3bdfSopenharmony_ci/* - Checked in the initial version to CVS */ 33f08c3bdfSopenharmony_ci/* */ 34f08c3bdfSopenharmony_ci/* Feb - 27 - 2001 Modified - Manoj Iyer, IBM Austin TX. */ 35f08c3bdfSopenharmony_ci/* - removed compiler warnings. */ 36f08c3bdfSopenharmony_ci/* - removed compiler errors. */ 37f08c3bdfSopenharmony_ci/* */ 38f08c3bdfSopenharmony_ci/* File: shm_test.c */ 39f08c3bdfSopenharmony_ci/* */ 40f08c3bdfSopenharmony_ci/* Description: This program is designed to stress the Memory management sub -*/ 41f08c3bdfSopenharmony_ci/* system of Linux. This program will spawn multiple pairs of */ 42f08c3bdfSopenharmony_ci/* reader and writer threads. One thread will create the shared */ 43f08c3bdfSopenharmony_ci/* segment of random size and write to this memory, the other */ 44f08c3bdfSopenharmony_ci/* pair will read from this memory. */ 45f08c3bdfSopenharmony_ci/* */ 46f08c3bdfSopenharmony_ci/******************************************************************************/ 47f08c3bdfSopenharmony_ci#include <pthread.h> /* required by pthread functions */ 48f08c3bdfSopenharmony_ci#include <stdio.h> /* required by fprintf() */ 49f08c3bdfSopenharmony_ci#include <stdlib.h> /* required by exit(), atoi() */ 50f08c3bdfSopenharmony_ci#include <string.h> /* required by strncpy() */ 51f08c3bdfSopenharmony_ci#include <unistd.h> /* required by getopt(), mmap() */ 52f08c3bdfSopenharmony_ci#include <sys/types.h> /* required by open(), shmat(), shmdt() */ 53f08c3bdfSopenharmony_ci#include <sys/stat.h> /* required by open() */ 54f08c3bdfSopenharmony_ci#include <sys/ipc.h> /* required by shmat() shmdt(), shmctl() */ 55f08c3bdfSopenharmony_ci#include <sys/shm.h> /* required by shmat() shmdt(), shmctl() */ 56f08c3bdfSopenharmony_ci#include <sys/mman.h> /* required by mmap() */ 57f08c3bdfSopenharmony_ci#include <fcntl.h> /* required by open() */ 58f08c3bdfSopenharmony_ci#include <stdint.h> /* required by uintptr_t */ 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_civoid noprintf(char *string, ...) 61f08c3bdfSopenharmony_ci{ 62f08c3bdfSopenharmony_ci} 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci#ifdef DEBUG 65f08c3bdfSopenharmony_ci#define dprt printf 66f08c3bdfSopenharmony_ci#else 67f08c3bdfSopenharmony_ci#define dprt noprintf 68f08c3bdfSopenharmony_ci#endif 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci#define PTHREAD_EXIT(val) do {\ 71f08c3bdfSopenharmony_ci exit_val = val; \ 72f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with %d\n", getpid(),exit_val); \ 73f08c3bdfSopenharmony_ci pthread_exit((void *)(uintptr_t)exit_val); \ 74f08c3bdfSopenharmony_ci } while (0) 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci#define OPT_MISSING(prog, opt) do{\ 77f08c3bdfSopenharmony_ci fprintf(stderr, "%s: option -%c ", prog, opt); \ 78f08c3bdfSopenharmony_ci fprintf(stderr, "requires an argument\n"); \ 79f08c3bdfSopenharmony_ci usage(prog); \ 80f08c3bdfSopenharmony_ci } while (0) 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci#define MAXT 30 /* default number of threads to create. */ 83f08c3bdfSopenharmony_ci#define MAXR 1000 /* default number of repatetions to execute */ 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_cistruct child_args 86f08c3bdfSopenharmony_ci{ 87f08c3bdfSopenharmony_ci pthread_t threadid; 88f08c3bdfSopenharmony_ci int num_reps; 89f08c3bdfSopenharmony_ci int shmkey; 90f08c3bdfSopenharmony_ci int map_size; 91f08c3bdfSopenharmony_ci int is_reader; 92f08c3bdfSopenharmony_ci}; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci/******************************************************************************/ 96f08c3bdfSopenharmony_ci/* */ 97f08c3bdfSopenharmony_ci/* Function: usage */ 98f08c3bdfSopenharmony_ci/* */ 99f08c3bdfSopenharmony_ci/* Description: Print the usage message. */ 100f08c3bdfSopenharmony_ci/* */ 101f08c3bdfSopenharmony_ci/* Return: exits with -1 */ 102f08c3bdfSopenharmony_ci/* */ 103f08c3bdfSopenharmony_ci/******************************************************************************/ 104f08c3bdfSopenharmony_cistatic void usage(char *progname) 105f08c3bdfSopenharmony_ci{ /* name of this program */ 106f08c3bdfSopenharmony_ci fprintf(stderr, 107f08c3bdfSopenharmony_ci "Usage: %s -d NUMDIR -f NUMFILES -h -t NUMTHRD\n" 108f08c3bdfSopenharmony_ci "\t -h Help!\n" 109f08c3bdfSopenharmony_ci "\t -l Number of repatetions to execute: Default: 1000\n" 110f08c3bdfSopenharmony_ci "\t -t Number of threads to generate: Default: 30\n", 111f08c3bdfSopenharmony_ci progname); 112f08c3bdfSopenharmony_ci exit(-1); 113f08c3bdfSopenharmony_ci} 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci/******************************************************************************/ 116f08c3bdfSopenharmony_ci/* */ 117f08c3bdfSopenharmony_ci/* Function: rm_shared_mem */ 118f08c3bdfSopenharmony_ci/* */ 119f08c3bdfSopenharmony_ci/* Description: This function removes the shared segments that were created */ 120f08c3bdfSopenharmony_ci/* This function is called when shmat fails or logical end of */ 121f08c3bdfSopenharmony_ci/* the while loop is reached in shmat_rd_wr function. */ 122f08c3bdfSopenharmony_ci/* */ 123f08c3bdfSopenharmony_ci/* Input: shm_id - id of the shared memory segment to be removed */ 124f08c3bdfSopenharmony_ci/* shm_addr - address of the shared memory segment to be removed */ 125f08c3bdfSopenharmony_ci/* cmd - remove id only or remove id and detach?? */ 126f08c3bdfSopenharmony_ci/* 0 - remove id dont detach segment. */ 127f08c3bdfSopenharmony_ci/* 1 - remove id and detach segment. */ 128f08c3bdfSopenharmony_ci/* */ 129f08c3bdfSopenharmony_ci/* Output: NONE. */ 130f08c3bdfSopenharmony_ci/* */ 131f08c3bdfSopenharmony_ci/* Return: exits with -1 on error, 0 on success */ 132f08c3bdfSopenharmony_ci/* */ 133f08c3bdfSopenharmony_ci/******************************************************************************/ 134f08c3bdfSopenharmony_cistatic int rm_shared_mem(key_t shm_id, /* id of shared memory segment to be removed */ 135f08c3bdfSopenharmony_ci char *shm_addr, /* address of shared mem seg to be removed */ 136f08c3bdfSopenharmony_ci int cmd) 137f08c3bdfSopenharmony_ci{ /* remove id only or remove id and detach seg */ 138f08c3bdfSopenharmony_ci struct shmid *shmbuf = NULL; /* info about the segment pointed by shmkey */ 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci dprt("pid[%d]: rm_shared_mem(): shm_id = %d shm_addr = %#x cmd = %d\n", 141f08c3bdfSopenharmony_ci getpid(), shm_id, shm_addr, cmd); 142f08c3bdfSopenharmony_ci if (shmctl(shm_id, IPC_RMID, (struct shmid_ds *)shmbuf) == -1) { 143f08c3bdfSopenharmony_ci dprt("pid[%d]: rm_shared_mem(): shmctl unable to remove shm_id[%d]\n", getpid(), shm_id); 144f08c3bdfSopenharmony_ci perror("rm_shared_mem(): shmctl()"); 145f08c3bdfSopenharmony_ci return -1; 146f08c3bdfSopenharmony_ci } 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci if (cmd) { 149f08c3bdfSopenharmony_ci if (shmdt((void *)shm_addr) == -1) { 150f08c3bdfSopenharmony_ci dprt("pid[%d]:rm_shared_mem(): shmdt unable to detach addr = %#x\n", getpid(), shm_addr); 151f08c3bdfSopenharmony_ci perror("rm_shared_mem(): shmdt()"); 152f08c3bdfSopenharmony_ci return -1; 153f08c3bdfSopenharmony_ci } 154f08c3bdfSopenharmony_ci } 155f08c3bdfSopenharmony_ci return 0; 156f08c3bdfSopenharmony_ci} 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci/******************************************************************************/ 159f08c3bdfSopenharmony_ci/* */ 160f08c3bdfSopenharmony_ci/* Function: shmat_rd_wr */ 161f08c3bdfSopenharmony_ci/* */ 162f08c3bdfSopenharmony_ci/* Description: This function repeatedly attaches and detaches the memory */ 163f08c3bdfSopenharmony_ci/* The size of the file is a multiple of page size. */ 164f08c3bdfSopenharmony_ci/* The function acts as either reader or writer thread depending */ 165f08c3bdfSopenharmony_ci/* on arg[3]. The reader and writer thread use the same key so */ 166f08c3bdfSopenharmony_ci/* they get access to the same shared memory segment. */ 167f08c3bdfSopenharmony_ci/* */ 168f08c3bdfSopenharmony_ci/* Input: The argument pointer contains the following. */ 169f08c3bdfSopenharmony_ci/* arg[0] - number of repatetions of the above operation */ 170f08c3bdfSopenharmony_ci/* arg[1] - shared memory key. */ 171f08c3bdfSopenharmony_ci/* arg[2] - size of the memory that is to be attached. */ 172f08c3bdfSopenharmony_ci/* arg[3] - reader or writer. */ 173f08c3bdfSopenharmony_ci/* */ 174f08c3bdfSopenharmony_ci/* Return: exits with -1 on error, 0 on success */ 175f08c3bdfSopenharmony_ci/* */ 176f08c3bdfSopenharmony_ci/******************************************************************************/ 177f08c3bdfSopenharmony_cistatic void *shmat_rd_wr(void *vargs) 178f08c3bdfSopenharmony_ci{ /* arguments to the thread function */ 179f08c3bdfSopenharmony_ci int shmndx = 0; /* index to the number of attach and detach */ 180f08c3bdfSopenharmony_ci int index = 0; /* index to the number of blocks touched */ 181f08c3bdfSopenharmony_ci key_t shm_id = 0; /* shared memory id */ 182f08c3bdfSopenharmony_ci struct child_args *args = vargs; 183f08c3bdfSopenharmony_ci volatile int exit_val = 0; /* exit value of the pthread */ 184f08c3bdfSopenharmony_ci char *read_from_mem; /* ptr to touch each (4096) block in memory */ 185f08c3bdfSopenharmony_ci char *write_to_mem; /* ptr to touch each (4096) block in memory */ 186f08c3bdfSopenharmony_ci char *shmat_addr; /* address of the attached memory */ 187f08c3bdfSopenharmony_ci char buff; /* temporary buffer */ 188f08c3bdfSopenharmony_ci 189f08c3bdfSopenharmony_ci while (shmndx++ < args->num_reps) { 190f08c3bdfSopenharmony_ci dprt("pid[%d]: shmat_rd_wr(): locargs[1] = %#x\n", 191f08c3bdfSopenharmony_ci getpid(), args->shmkey); 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci /* get shared memory id */ 194f08c3bdfSopenharmony_ci if ((shm_id = 195f08c3bdfSopenharmony_ci shmget(args->shmkey, args->map_size, IPC_CREAT | 0666)) 196f08c3bdfSopenharmony_ci == -1) { 197f08c3bdfSopenharmony_ci dprt("pid[%d]: shmat_rd_wr(): shmget failed\n", 198f08c3bdfSopenharmony_ci getpid()); 199f08c3bdfSopenharmony_ci perror("do_shmat_shmadt(): shmget()"); 200f08c3bdfSopenharmony_ci PTHREAD_EXIT(-1); 201f08c3bdfSopenharmony_ci } 202f08c3bdfSopenharmony_ci 203f08c3bdfSopenharmony_ci fprintf(stdout, "pid[%d]: shmat_rd_wr(): shmget():" 204f08c3bdfSopenharmony_ci "success got segment id %d\n", getpid(), shm_id); 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci /* get shared memory segment */ 207f08c3bdfSopenharmony_ci if ((shmat_addr = shmat(shm_id, NULL, 0)) == (void *)-1) { 208f08c3bdfSopenharmony_ci rm_shared_mem(shm_id, shmat_addr, 0); 209f08c3bdfSopenharmony_ci fprintf(stderr, 210f08c3bdfSopenharmony_ci "pid[%d]: do_shmat_shmadt(): shmat_addr = %#lx\n", 211f08c3bdfSopenharmony_ci getpid(), (long)shmat_addr); 212f08c3bdfSopenharmony_ci perror("do_shmat_shmadt(): shmat()"); 213f08c3bdfSopenharmony_ci PTHREAD_EXIT(-1); 214f08c3bdfSopenharmony_ci } 215f08c3bdfSopenharmony_ci dprt("pid[%d]: do_shmat_shmadt(): content of memory shmat_addr = %s\n", getpid(), shmat_addr); 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci fprintf(stdout, 218f08c3bdfSopenharmony_ci "pid[%d]: do_shmat_shmadt(): got shmat address = %#lx\n", 219f08c3bdfSopenharmony_ci getpid(), (long)shmat_addr); 220f08c3bdfSopenharmony_ci 221f08c3bdfSopenharmony_ci if (args->is_reader) { 222f08c3bdfSopenharmony_ci /* write character 'Y' to that memory area */ 223f08c3bdfSopenharmony_ci index = 0; 224f08c3bdfSopenharmony_ci write_to_mem = shmat_addr; 225f08c3bdfSopenharmony_ci while (index < args->map_size) { 226f08c3bdfSopenharmony_ci dprt("pid[%d]: do_shmat_shmatd(): write_to_mem = %#x\n", getpid(), write_to_mem); 227f08c3bdfSopenharmony_ci *write_to_mem = 'Y'; 228f08c3bdfSopenharmony_ci index++; 229f08c3bdfSopenharmony_ci write_to_mem++; 230f08c3bdfSopenharmony_ci sched_yield(); 231f08c3bdfSopenharmony_ci } 232f08c3bdfSopenharmony_ci } else { 233f08c3bdfSopenharmony_ci /* read from the memory area */ 234f08c3bdfSopenharmony_ci index = 0; 235f08c3bdfSopenharmony_ci read_from_mem = shmat_addr; 236f08c3bdfSopenharmony_ci while (index < args->map_size) { 237f08c3bdfSopenharmony_ci buff = *read_from_mem; 238f08c3bdfSopenharmony_ci index++; 239f08c3bdfSopenharmony_ci read_from_mem++; 240f08c3bdfSopenharmony_ci sched_yield(); 241f08c3bdfSopenharmony_ci } 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci sched_yield(); 245f08c3bdfSopenharmony_ci 246f08c3bdfSopenharmony_ci /* remove the shared memory */ 247f08c3bdfSopenharmony_ci if (rm_shared_mem(shm_id, shmat_addr, 1) == -1) { 248f08c3bdfSopenharmony_ci fprintf(stderr, 249f08c3bdfSopenharmony_ci "pid[%d]: do_shmat_shmatd(): rm_shared_mem(): faild to rm id\n", 250f08c3bdfSopenharmony_ci getpid()); 251f08c3bdfSopenharmony_ci PTHREAD_EXIT(-1); 252f08c3bdfSopenharmony_ci } 253f08c3bdfSopenharmony_ci } 254f08c3bdfSopenharmony_ci 255f08c3bdfSopenharmony_ci PTHREAD_EXIT(0); 256f08c3bdfSopenharmony_ci} 257f08c3bdfSopenharmony_ci 258f08c3bdfSopenharmony_ci/******************************************************************************/ 259f08c3bdfSopenharmony_ci/* */ 260f08c3bdfSopenharmony_ci/* Function: main */ 261f08c3bdfSopenharmony_ci/* */ 262f08c3bdfSopenharmony_ci/* Description: This is the entry point to the program. This function will */ 263f08c3bdfSopenharmony_ci/* parse the input arguments and set the values accordingly. If */ 264f08c3bdfSopenharmony_ci/* no arguments (or desired) are provided default values are used*/ 265f08c3bdfSopenharmony_ci/* refer the usage function for the arguments that this program */ 266f08c3bdfSopenharmony_ci/* takes. It also creates the threads which do most of the dirty */ 267f08c3bdfSopenharmony_ci/* work. If the threads exits with a value '0' the program exits */ 268f08c3bdfSopenharmony_ci/* with success '0' else it exits with failure '-1'. */ 269f08c3bdfSopenharmony_ci/* */ 270f08c3bdfSopenharmony_ci/* Return: -1 on failure */ 271f08c3bdfSopenharmony_ci/* 0 on success */ 272f08c3bdfSopenharmony_ci/* */ 273f08c3bdfSopenharmony_ci/******************************************************************************/ 274f08c3bdfSopenharmony_ciint main(int argc, /* number of input parameters */ 275f08c3bdfSopenharmony_ci char **argv) 276f08c3bdfSopenharmony_ci{ /* pointer to the command line arguments. */ 277f08c3bdfSopenharmony_ci int c; /* command line options */ 278f08c3bdfSopenharmony_ci int num_thrd = MAXT; /* number of threads to create */ 279f08c3bdfSopenharmony_ci int num_reps = MAXR; /* number of repatitions the test is run */ 280f08c3bdfSopenharmony_ci int i; 281f08c3bdfSopenharmony_ci void *th_status; /* exit status of LWP's */ 282f08c3bdfSopenharmony_ci int map_size; /* size of the file mapped. */ 283f08c3bdfSopenharmony_ci int shmkey = 1969; /* key used to generate shmid by shmget() */ 284f08c3bdfSopenharmony_ci struct child_args chld_args[30]; /* arguments to the thread function */ 285f08c3bdfSopenharmony_ci char *map_address = NULL; 286f08c3bdfSopenharmony_ci /* address in memory of the mapped file */ 287f08c3bdfSopenharmony_ci extern int optopt; /* options to the program */ 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, "hl:t:")) != -1) { 290f08c3bdfSopenharmony_ci switch (c) { 291f08c3bdfSopenharmony_ci case 'h': 292f08c3bdfSopenharmony_ci usage(argv[0]); 293f08c3bdfSopenharmony_ci break; 294f08c3bdfSopenharmony_ci case 'l': /* how many repetitions of the test to exec */ 295f08c3bdfSopenharmony_ci if ((num_reps = atoi(optarg)) == 0) 296f08c3bdfSopenharmony_ci OPT_MISSING(argv[0], optopt); 297f08c3bdfSopenharmony_ci else if (num_reps < 0) { 298f08c3bdfSopenharmony_ci fprintf(stdout, 299f08c3bdfSopenharmony_ci "WARNING: bad argument. Using default\n"); 300f08c3bdfSopenharmony_ci num_reps = MAXR; 301f08c3bdfSopenharmony_ci } 302f08c3bdfSopenharmony_ci break; 303f08c3bdfSopenharmony_ci case 't': 304f08c3bdfSopenharmony_ci if ((num_thrd = atoi(optarg)) == 0) 305f08c3bdfSopenharmony_ci OPT_MISSING(argv[0], optopt); 306f08c3bdfSopenharmony_ci else if (num_thrd < 0 || num_thrd > MAXT) { 307f08c3bdfSopenharmony_ci fprintf(stdout, 308f08c3bdfSopenharmony_ci "WARNING: bad argument. Using default\n"); 309f08c3bdfSopenharmony_ci num_thrd = MAXT; 310f08c3bdfSopenharmony_ci } 311f08c3bdfSopenharmony_ci break; 312f08c3bdfSopenharmony_ci default: 313f08c3bdfSopenharmony_ci usage(argv[0]); 314f08c3bdfSopenharmony_ci break; 315f08c3bdfSopenharmony_ci } 316f08c3bdfSopenharmony_ci } 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci for (i = 0; i < num_thrd; i += 2) { 319f08c3bdfSopenharmony_ci srand(time(NULL) % 100); 320f08c3bdfSopenharmony_ci map_size = (1 + (int)(1000.0 * rand() / (RAND_MAX + 1.0))) * 4096; 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_ci dprt("main(): thrd_ndx = %d map_address = %#x map_size = %d\n", 323f08c3bdfSopenharmony_ci i, map_address, map_size); 324f08c3bdfSopenharmony_ci 325f08c3bdfSopenharmony_ci chld_args[i].num_reps = num_reps; 326f08c3bdfSopenharmony_ci chld_args[i].map_size = map_size; 327f08c3bdfSopenharmony_ci chld_args[i].shmkey = shmkey++; 328f08c3bdfSopenharmony_ci chld_args[i].is_reader = 0; 329f08c3bdfSopenharmony_ci if (pthread_create 330f08c3bdfSopenharmony_ci (&chld_args[i].threadid, NULL, shmat_rd_wr, &chld_args[i])) { 331f08c3bdfSopenharmony_ci perror("shmat_rd_wr(): pthread_create()"); 332f08c3bdfSopenharmony_ci exit(-1); 333f08c3bdfSopenharmony_ci } 334f08c3bdfSopenharmony_ci 335f08c3bdfSopenharmony_ci chld_args[i + 1] = chld_args[i]; 336f08c3bdfSopenharmony_ci chld_args[i + 1].is_reader = 1; 337f08c3bdfSopenharmony_ci if (pthread_create 338f08c3bdfSopenharmony_ci (&chld_args[i + 1].threadid, NULL, shmat_rd_wr, &chld_args[i + 1])) { 339f08c3bdfSopenharmony_ci perror("shmat_rd_wr(): pthread_create()"); 340f08c3bdfSopenharmony_ci exit(-1); 341f08c3bdfSopenharmony_ci } 342f08c3bdfSopenharmony_ci } 343f08c3bdfSopenharmony_ci 344f08c3bdfSopenharmony_ci sync(); 345f08c3bdfSopenharmony_ci 346f08c3bdfSopenharmony_ci for (i = 0; i < num_thrd; i++) { 347f08c3bdfSopenharmony_ci if (pthread_join(chld_args[i].threadid, &th_status) != 0) { 348f08c3bdfSopenharmony_ci perror("shmat_rd_wr(): pthread_join()"); 349f08c3bdfSopenharmony_ci exit(-1); 350f08c3bdfSopenharmony_ci } else { 351f08c3bdfSopenharmony_ci dprt("WE ARE HERE %d\n", __LINE__); 352f08c3bdfSopenharmony_ci if (th_status == (void *)-1) { 353f08c3bdfSopenharmony_ci fprintf(stderr, 354f08c3bdfSopenharmony_ci "thread [%ld] - process exited with errors\n", 355f08c3bdfSopenharmony_ci (long)chld_args[i].threadid); 356f08c3bdfSopenharmony_ci exit(-1); 357f08c3bdfSopenharmony_ci } 358f08c3bdfSopenharmony_ci } 359f08c3bdfSopenharmony_ci } 360f08c3bdfSopenharmony_ci exit(0); 361f08c3bdfSopenharmony_ci} 362