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: July - 16 - 2001 Created by Manoj Iyer, IBM Austin TX. */ 24f08c3bdfSopenharmony_ci/* email:manjo@austin.ibm.com */ 25f08c3bdfSopenharmony_ci/* */ 26f08c3bdfSopenharmony_ci/* July - 30 - 2001 Modified - Added function write_to_mem. */ 27f08c3bdfSopenharmony_ci/* */ 28f08c3bdfSopenharmony_ci/* Aug - 14 - 2001 Modified - Added code to remove the shared */ 29f08c3bdfSopenharmony_ci/* memory segment ids. */ 30f08c3bdfSopenharmony_ci/* */ 31f08c3bdfSopenharmony_ci/* Aug - 15 - 2001 Modified - Added for loop to run the test */ 32f08c3bdfSopenharmony_ci/* repeatedly. */ 33f08c3bdfSopenharmony_ci/* */ 34f08c3bdfSopenharmony_ci/* Oct - 22 - 2001 Modified - Fixed bad code in main(). */ 35f08c3bdfSopenharmony_ci/* removed stray code and options. Pthread_join */ 36f08c3bdfSopenharmony_ci/* part fixed, older version was completely bad */ 37f08c3bdfSopenharmony_ci/* */ 38f08c3bdfSopenharmony_ci/* Nov - 09 - 2001 Modified - Removed compile errors */ 39f08c3bdfSopenharmony_ci/* - added missing header file string.h */ 40f08c3bdfSopenharmony_ci/* - removed unused variables. */ 41f08c3bdfSopenharmony_ci/* - made read_ndx and write_ndx static variable*/ 42f08c3bdfSopenharmony_ci/* */ 43f08c3bdfSopenharmony_ci/* Nov - 91 - 2001 Modified - Changed scope of status variable */ 44f08c3bdfSopenharmony_ci/* - change the status of status variable from */ 45f08c3bdfSopenharmony_ci/* int *status to int status[1] */ 46f08c3bdfSopenharmony_ci/* */ 47f08c3bdfSopenharmony_ci/* File: shmat1.c */ 48f08c3bdfSopenharmony_ci/* */ 49f08c3bdfSopenharmony_ci/* Description: Test the LINUX memory manager. The program is aimed at */ 50f08c3bdfSopenharmony_ci/* stressing the memory manager by repeaded shmat/write/read/ */ 51f08c3bdfSopenharmony_ci/* shmatd of file/memory of random size (maximum 1000 * 4096) */ 52f08c3bdfSopenharmony_ci/* done by multiple processes. */ 53f08c3bdfSopenharmony_ci/* */ 54f08c3bdfSopenharmony_ci/* Create a file of random size upto 1000 times 4096. */ 55f08c3bdfSopenharmony_ci/* process X shmats and un-shmats this file in memory. */ 56f08c3bdfSopenharmony_ci/* process Y changes content of the file to Y, ie writes to it. */ 57f08c3bdfSopenharmony_ci/* process Z reads from this memory location, and varifies the */ 58f08c3bdfSopenharmony_ci/* the content of the file. */ 59f08c3bdfSopenharmony_ci/* */ 60f08c3bdfSopenharmony_ci/******************************************************************************/ 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci/* Include Files */ 63f08c3bdfSopenharmony_ci#include <stdio.h> /* definitions for standard I/O */ 64f08c3bdfSopenharmony_ci#include <unistd.h> /* required by usleep() */ 65f08c3bdfSopenharmony_ci#include <errno.h> /* definitions for errno */ 66f08c3bdfSopenharmony_ci#include <sched.h> /* definitions for sched_yield() */ 67f08c3bdfSopenharmony_ci#include <stdlib.h> /* definitions for WEXIT macros */ 68f08c3bdfSopenharmony_ci#include <signal.h> /* required by sigaction & sig handling fncs */ 69f08c3bdfSopenharmony_ci#include <sys/time.h> /* definitions of settimer() */ 70f08c3bdfSopenharmony_ci#include <sys/wait.h> /* definitions of itimer structure */ 71f08c3bdfSopenharmony_ci#include <pthread.h> /* definitions for pthread_create etc */ 72f08c3bdfSopenharmony_ci#include <setjmp.h> /* required by setjmp longjmp */ 73f08c3bdfSopenharmony_ci#include <sys/ucontext.h> /* required by the signal handler */ 74f08c3bdfSopenharmony_ci#include <sys/ipc.h> /* required by shmat shmget etc */ 75f08c3bdfSopenharmony_ci#include <sys/shm.h> /* required by shmat shmget etc */ 76f08c3bdfSopenharmony_ci#include <string.h> /* required by strncmp */ 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci/* Defines */ 79f08c3bdfSopenharmony_ci#ifndef TRUE 80f08c3bdfSopenharmony_ci#define TRUE 1 81f08c3bdfSopenharmony_ci#endif 82f08c3bdfSopenharmony_ci#ifndef FALSE 83f08c3bdfSopenharmony_ci#define FALSE 0 84f08c3bdfSopenharmony_ci#endif 85f08c3bdfSopenharmony_ci#define prtln() printf(" I AM HERE ==> %s %d\n", __FILE__, __LINE__); 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci#define STR_SHMAT " " 88f08c3bdfSopenharmony_ci#define STR_WRITER " " 89f08c3bdfSopenharmony_ci#define STR_READER " " 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci/* Global Variables */ 92f08c3bdfSopenharmony_civoid *map_address; /* pointer to file in memory */ 93f08c3bdfSopenharmony_cisigjmp_buf jmpbuf; /* argument to setjmp and longjmp */ 94f08c3bdfSopenharmony_ciint fsize; /* size of the file to be created. */ 95f08c3bdfSopenharmony_ciint done_shmat = 0; /* disallow read and writes before shmat */ 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci/******************************************************************************/ 98f08c3bdfSopenharmony_ci/* */ 99f08c3bdfSopenharmony_ci/* Function: sig_handler */ 100f08c3bdfSopenharmony_ci/* */ 101f08c3bdfSopenharmony_ci/* Description: handle SIGALRM raised by set_timer(), SIGALRM is raised when */ 102f08c3bdfSopenharmony_ci/* the timer expires. If any other signal is received exit the */ 103f08c3bdfSopenharmony_ci/* test. */ 104f08c3bdfSopenharmony_ci/* */ 105f08c3bdfSopenharmony_ci/* Input: signal - signal number, intrested in SIGALRM! */ 106f08c3bdfSopenharmony_ci/* */ 107f08c3bdfSopenharmony_ci/* Return: exit -1 if unexpected signal is received */ 108f08c3bdfSopenharmony_ci/* exit 0 if SIGALRM is received */ 109f08c3bdfSopenharmony_ci/* */ 110f08c3bdfSopenharmony_ci/******************************************************************************/ 111f08c3bdfSopenharmony_cistatic void sig_handler(int signal, /* signal number, set to handle SIGALRM */ 112f08c3bdfSopenharmony_ci int code, ucontext_t *ut) 113f08c3bdfSopenharmony_ci{ /* contains pointer to sigcontext structure */ 114f08c3bdfSopenharmony_ci#ifdef __i386__ 115f08c3bdfSopenharmony_ci unsigned long except; /* exception type. */ 116f08c3bdfSopenharmony_ci int ret = 0; /* exit code from signal handler. */ 117f08c3bdfSopenharmony_ci struct sigcontext *scp = /* pointer to sigcontext structure */ 118f08c3bdfSopenharmony_ci (struct sigcontext *)&ut->uc_mcontext; 119f08c3bdfSopenharmony_ci#endif 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ci if (signal == SIGALRM) { 122f08c3bdfSopenharmony_ci fprintf(stdout, "Test ended, success\n"); 123f08c3bdfSopenharmony_ci exit(0); 124f08c3bdfSopenharmony_ci } 125f08c3bdfSopenharmony_ci#ifdef __i386__ 126f08c3bdfSopenharmony_ci else { 127f08c3bdfSopenharmony_ci except = scp->trapno; 128f08c3bdfSopenharmony_ci fprintf(stderr, "signal caught - [%d] ", signal); 129f08c3bdfSopenharmony_ci } 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci switch (except) { 132f08c3bdfSopenharmony_ci case 10: 133f08c3bdfSopenharmony_ci fprintf(stderr, 134f08c3bdfSopenharmony_ci "Exception - invalid TSS, exception #[%ld]\n", except); 135f08c3bdfSopenharmony_ci break; 136f08c3bdfSopenharmony_ci case 11: 137f08c3bdfSopenharmony_ci fprintf(stderr, 138f08c3bdfSopenharmony_ci "Exception - segment not present, exception #[%ld]\n", 139f08c3bdfSopenharmony_ci except); 140f08c3bdfSopenharmony_ci break; 141f08c3bdfSopenharmony_ci case 12: 142f08c3bdfSopenharmony_ci fprintf(stderr, 143f08c3bdfSopenharmony_ci "Exception - stack segment not present, exception #[%ld]\n", 144f08c3bdfSopenharmony_ci except); 145f08c3bdfSopenharmony_ci break; 146f08c3bdfSopenharmony_ci case 13: 147f08c3bdfSopenharmony_ci fprintf(stderr, 148f08c3bdfSopenharmony_ci "Exception - general protection, exception #[%ld]\n", 149f08c3bdfSopenharmony_ci except); 150f08c3bdfSopenharmony_ci break; 151f08c3bdfSopenharmony_ci case 14: 152f08c3bdfSopenharmony_ci fprintf(stderr, 153f08c3bdfSopenharmony_ci "Exception - page fault, exception #[%ld]\n", except); 154f08c3bdfSopenharmony_ci ret = 1; 155f08c3bdfSopenharmony_ci break; 156f08c3bdfSopenharmony_ci default: 157f08c3bdfSopenharmony_ci fprintf(stderr, 158f08c3bdfSopenharmony_ci "Exception type not handled... unknown exception #[%ld]\n", 159f08c3bdfSopenharmony_ci except); 160f08c3bdfSopenharmony_ci break; 161f08c3bdfSopenharmony_ci } 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci if (ret) { 164f08c3bdfSopenharmony_ci if (scp->edi == (int)map_address) { 165f08c3bdfSopenharmony_ci fprintf(stdout, 166f08c3bdfSopenharmony_ci "page fault at [%#lx] - ignore\n", scp->edi); 167f08c3bdfSopenharmony_ci siglongjmp(jmpbuf, 1); 168f08c3bdfSopenharmony_ci } else if (scp->esi == (int)map_address) { 169f08c3bdfSopenharmony_ci fprintf(stdout, 170f08c3bdfSopenharmony_ci "page fault at [%#lx] - ignore\n", scp->esi); 171f08c3bdfSopenharmony_ci siglongjmp(jmpbuf, 1); 172f08c3bdfSopenharmony_ci } else { 173f08c3bdfSopenharmony_ci fprintf(stderr, 174f08c3bdfSopenharmony_ci "address at which sigfault occured: [%lx]\n" 175f08c3bdfSopenharmony_ci "address at which sigfault occured: [%lx]\n" 176f08c3bdfSopenharmony_ci "address at which memory was shmat: [%p]\n", 177f08c3bdfSopenharmony_ci (unsigned long)scp->edi, 178f08c3bdfSopenharmony_ci (unsigned long)scp->esi, map_address); 179f08c3bdfSopenharmony_ci fprintf(stderr, "bad page fault exit test\n"); 180f08c3bdfSopenharmony_ci exit(-1); 181f08c3bdfSopenharmony_ci } 182f08c3bdfSopenharmony_ci } else 183f08c3bdfSopenharmony_ci exit(-1); 184f08c3bdfSopenharmony_ci#else 185f08c3bdfSopenharmony_ci fprintf(stderr, "caught signal %d -- exiting.\n", signal); 186f08c3bdfSopenharmony_ci exit(-1); 187f08c3bdfSopenharmony_ci#endif 188f08c3bdfSopenharmony_ci} 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci /******************************************************************************//* */ 191f08c3bdfSopenharmony_ci/* Function: usage */ 192f08c3bdfSopenharmony_ci/* */ 193f08c3bdfSopenharmony_ci/* Description: Print the usage message. */ 194f08c3bdfSopenharmony_ci/* */ 195f08c3bdfSopenharmony_ci/* Return: exits with -1 */ 196f08c3bdfSopenharmony_ci/* */ 197f08c3bdfSopenharmony_ci/******************************************************************************/ 198f08c3bdfSopenharmony_cistatic void usage(char *progname) 199f08c3bdfSopenharmony_ci{ /* name of this program */ 200f08c3bdfSopenharmony_ci fprintf(stderr, 201f08c3bdfSopenharmony_ci "Usage: %s -h -l -x\n" 202f08c3bdfSopenharmony_ci "\t -h help, usage message.\n" 203f08c3bdfSopenharmony_ci "\t -l number of map - write - unmap. default: 1000\n" 204f08c3bdfSopenharmony_ci "\t -x time for which test is to be run. default: 24 Hrs\n", 205f08c3bdfSopenharmony_ci progname); 206f08c3bdfSopenharmony_ci exit(-1); 207f08c3bdfSopenharmony_ci} 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci/******************************************************************************/ 210f08c3bdfSopenharmony_ci/* */ 211f08c3bdfSopenharmony_ci/* Function: shmat_shmdt */ 212f08c3bdfSopenharmony_ci/* */ 213f08c3bdfSopenharmony_ci/* Description: Thread X function. */ 214f08c3bdfSopenharmony_ci/* shmat a random size file and shm-detach this file, this is */ 215f08c3bdfSopenharmony_ci/* done for user defined number of times. */ 216f08c3bdfSopenharmony_ci/* */ 217f08c3bdfSopenharmony_ci/* Input: arg[0] number of times shmat shmdt is done */ 218f08c3bdfSopenharmony_ci/* */ 219f08c3bdfSopenharmony_ci/* Return: -1 on error. */ 220f08c3bdfSopenharmony_ci/* 0 on errorless completion of the loop. */ 221f08c3bdfSopenharmony_ci/* */ 222f08c3bdfSopenharmony_ci/******************************************************************************/ 223f08c3bdfSopenharmony_civoid *shmat_shmdt(void *args) 224f08c3bdfSopenharmony_ci{ /* arguments to the thread X function. */ 225f08c3bdfSopenharmony_ci int shm_ndx = 0; /* index to number of shmat/shmdt */ 226f08c3bdfSopenharmony_ci key_t shmkey = 0; /* IPC_PRIVATE (key for shmget) */ 227f08c3bdfSopenharmony_ci int shmid; /* shared memory id */ 228f08c3bdfSopenharmony_ci long *locargs = /* local pointer to arguments */ 229f08c3bdfSopenharmony_ci (long *)args; 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_ci while (shm_ndx++ < (int)locargs[0]) { 232f08c3bdfSopenharmony_ci /* put the reader and writer threads to sleep */ 233f08c3bdfSopenharmony_ci done_shmat = 0; 234f08c3bdfSopenharmony_ci 235f08c3bdfSopenharmony_ci /* generate a random size, we will ask for this amount of shared mem */ 236f08c3bdfSopenharmony_ci srand(time(NULL) % 100); 237f08c3bdfSopenharmony_ci fsize = (1 + (int)(1000.0 * rand() / (RAND_MAX + 1.0))) * 4096; 238f08c3bdfSopenharmony_ci 239f08c3bdfSopenharmony_ci if ((shmid = shmget(shmkey, fsize, IPC_CREAT | 0666)) == -1) { 240f08c3bdfSopenharmony_ci perror("shmat_shmdt(): shmget()"); 241f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 242f08c3bdfSopenharmony_ci } else { 243f08c3bdfSopenharmony_ci fprintf(stdout, 244f08c3bdfSopenharmony_ci "%s[%#lx]: shmget(): success, got segment of size %d\n", 245f08c3bdfSopenharmony_ci STR_SHMAT, pthread_self(), fsize); 246f08c3bdfSopenharmony_ci } 247f08c3bdfSopenharmony_ci 248f08c3bdfSopenharmony_ci if ((map_address = shmat(shmid, NULL, 0)) 249f08c3bdfSopenharmony_ci == (void *)-1) { 250f08c3bdfSopenharmony_ci fprintf(stderr, "shmat_shmat(): map address = %p\n", 251f08c3bdfSopenharmony_ci map_address); 252f08c3bdfSopenharmony_ci perror("shmat_shmdt(): shmat()"); 253f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 254f08c3bdfSopenharmony_ci } else { 255f08c3bdfSopenharmony_ci /* Wake up the reader and writer threads. */ 256f08c3bdfSopenharmony_ci /* Write 'X' into map_address. We are not sure about 257f08c3bdfSopenharmony_ci reader/writer interleaving. So the reader may expect 258f08c3bdfSopenharmony_ci to find 'X' or 'Y' 259f08c3bdfSopenharmony_ci */ 260f08c3bdfSopenharmony_ci memset(map_address, 'X', 1); 261f08c3bdfSopenharmony_ci done_shmat = 1; 262f08c3bdfSopenharmony_ci usleep(0); 263f08c3bdfSopenharmony_ci } 264f08c3bdfSopenharmony_ci 265f08c3bdfSopenharmony_ci fprintf(stdout, "%s[%#lx]: Map address = %p\n", 266f08c3bdfSopenharmony_ci STR_SHMAT, pthread_self(), map_address); 267f08c3bdfSopenharmony_ci fprintf(stdout, 268f08c3bdfSopenharmony_ci "%s[%#lx]: Num iter: [%d] Total Num Iter: [%d]\n", 269f08c3bdfSopenharmony_ci STR_SHMAT, pthread_self(), shm_ndx, (int)locargs[0]); 270f08c3bdfSopenharmony_ci usleep(0); 271f08c3bdfSopenharmony_ci sched_yield(); 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci /* put the threads to sleep before un-shmatting */ 274f08c3bdfSopenharmony_ci done_shmat = 0; 275f08c3bdfSopenharmony_ci if (shmdt((void *)map_address) == -1) { 276f08c3bdfSopenharmony_ci perror("shmat_shmdt(): shmdt()"); 277f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 278f08c3bdfSopenharmony_ci } 279f08c3bdfSopenharmony_ci if (shmctl(shmid, IPC_RMID, NULL)) { 280f08c3bdfSopenharmony_ci perror("shmat_shmdt(): shmctl()"); 281f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 282f08c3bdfSopenharmony_ci } 283f08c3bdfSopenharmony_ci } 284f08c3bdfSopenharmony_ci pthread_exit(NULL); 285f08c3bdfSopenharmony_ci} 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci/******************************************************************************/ 288f08c3bdfSopenharmony_ci/* */ 289f08c3bdfSopenharmony_ci/* Function: write_to_mem */ 290f08c3bdfSopenharmony_ci/* */ 291f08c3bdfSopenharmony_ci/* Description: Thread Y function. */ 292f08c3bdfSopenharmony_ci/* Writes 'Y' to the memory location shmat by process X. */ 293f08c3bdfSopenharmony_ci/* */ 294f08c3bdfSopenharmony_ci/* Input: arg[0] number of times write is performed */ 295f08c3bdfSopenharmony_ci/* */ 296f08c3bdfSopenharmony_ci/* Return: -1 on error. */ 297f08c3bdfSopenharmony_ci/* 0 on errorless completion of the loop. */ 298f08c3bdfSopenharmony_ci/* */ 299f08c3bdfSopenharmony_ci/******************************************************************************/ 300f08c3bdfSopenharmony_civoid *write_to_mem(void *args) 301f08c3bdfSopenharmony_ci{ 302f08c3bdfSopenharmony_ci static int write_ndx = 0; /* index to the number of writes to perform */ 303f08c3bdfSopenharmony_ci long *locargs = /* local pointer to the arguments */ 304f08c3bdfSopenharmony_ci (long *)args; 305f08c3bdfSopenharmony_ci 306f08c3bdfSopenharmony_ci while (write_ndx++ < (int)locargs[0]) { 307f08c3bdfSopenharmony_ci /* wait for the thread to shmat, and dont sleep on the processor. */ 308f08c3bdfSopenharmony_ci while (!done_shmat) 309f08c3bdfSopenharmony_ci usleep(0); 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci if (sigsetjmp(jmpbuf, 1) == 1) { 312f08c3bdfSopenharmony_ci fprintf(stdout, 313f08c3bdfSopenharmony_ci "page fault ocurred due a write after an shmdt from [%p]\n", 314f08c3bdfSopenharmony_ci map_address); 315f08c3bdfSopenharmony_ci } 316f08c3bdfSopenharmony_ci 317f08c3bdfSopenharmony_ci fprintf(stdout, 318f08c3bdfSopenharmony_ci "%s[%#lx]: write_to_mem(): memory address: [%p]\n", 319f08c3bdfSopenharmony_ci STR_WRITER, pthread_self(), map_address); 320f08c3bdfSopenharmony_ci memset(map_address, 'Y', 1); 321f08c3bdfSopenharmony_ci usleep(1); 322f08c3bdfSopenharmony_ci sched_yield(); 323f08c3bdfSopenharmony_ci } 324f08c3bdfSopenharmony_ci pthread_exit(NULL); 325f08c3bdfSopenharmony_ci} 326f08c3bdfSopenharmony_ci 327f08c3bdfSopenharmony_ci/******************************************************************************/ 328f08c3bdfSopenharmony_ci/* */ 329f08c3bdfSopenharmony_ci/* Function: read_from_mem */ 330f08c3bdfSopenharmony_ci/* */ 331f08c3bdfSopenharmony_ci/* Description: Thread Z function. */ 332f08c3bdfSopenharmony_ci/* reads from the memory location shmat by process X. */ 333f08c3bdfSopenharmony_ci/* */ 334f08c3bdfSopenharmony_ci/* Input: arg[0] number of times read is performed */ 335f08c3bdfSopenharmony_ci/* */ 336f08c3bdfSopenharmony_ci/* Return: -1 on error. */ 337f08c3bdfSopenharmony_ci/* 0 on errorless completion of the loop. */ 338f08c3bdfSopenharmony_ci/* */ 339f08c3bdfSopenharmony_ci/******************************************************************************/ 340f08c3bdfSopenharmony_civoid *read_from_mem(void *args) 341f08c3bdfSopenharmony_ci{ 342f08c3bdfSopenharmony_ci static int read_ndx = 0; /* index to the number of writes to perform */ 343f08c3bdfSopenharmony_ci long *locargs = /* local pointer to the arguments */ 344f08c3bdfSopenharmony_ci (long *)args; 345f08c3bdfSopenharmony_ci 346f08c3bdfSopenharmony_ci while (read_ndx++ < (int)locargs[0]) { 347f08c3bdfSopenharmony_ci /* wait for the shmat to happen */ 348f08c3bdfSopenharmony_ci while (!done_shmat) 349f08c3bdfSopenharmony_ci usleep(0); 350f08c3bdfSopenharmony_ci 351f08c3bdfSopenharmony_ci fprintf(stdout, 352f08c3bdfSopenharmony_ci "%s[%#lx]: read_from_mem(): memory address: [%p]\n", 353f08c3bdfSopenharmony_ci STR_READER, pthread_self(), map_address); 354f08c3bdfSopenharmony_ci if (sigsetjmp(jmpbuf, 1) == 1) { 355f08c3bdfSopenharmony_ci fprintf(stdout, 356f08c3bdfSopenharmony_ci "page fault ocurred due a read after an shmdt from %p\n", 357f08c3bdfSopenharmony_ci map_address); 358f08c3bdfSopenharmony_ci } 359f08c3bdfSopenharmony_ci 360f08c3bdfSopenharmony_ci fprintf(stdout, "%s[%#lx]: read_mem(): content of memory: %s\n", 361f08c3bdfSopenharmony_ci STR_READER, pthread_self(), (char *)map_address); 362f08c3bdfSopenharmony_ci 363f08c3bdfSopenharmony_ci if (strncmp(map_address, "Y", 1) != 0) { 364f08c3bdfSopenharmony_ci if (strncmp(map_address, "X", 1) != 0) { 365f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 366f08c3bdfSopenharmony_ci } 367f08c3bdfSopenharmony_ci } 368f08c3bdfSopenharmony_ci usleep(1); 369f08c3bdfSopenharmony_ci sched_yield(); 370f08c3bdfSopenharmony_ci } 371f08c3bdfSopenharmony_ci pthread_exit(NULL); 372f08c3bdfSopenharmony_ci} 373f08c3bdfSopenharmony_ci 374f08c3bdfSopenharmony_ci/******************************************************************************/ 375f08c3bdfSopenharmony_ci/* */ 376f08c3bdfSopenharmony_ci/* Function: main */ 377f08c3bdfSopenharmony_ci/* */ 378f08c3bdfSopenharmony_ci/* Descrption: Create a large file of size up to a Giga Bytes. write to it */ 379f08c3bdfSopenharmony_ci/* lower case alphabet 'a'. Map the file and change the contents */ 380f08c3bdfSopenharmony_ci/* to 'A's (upper case alphabet), write the contents to the file,*/ 381f08c3bdfSopenharmony_ci/* and unmap the file from memory. Spwan a certian number of */ 382f08c3bdfSopenharmony_ci/* LWP's that will do the above. */ 383f08c3bdfSopenharmony_ci/* */ 384f08c3bdfSopenharmony_ci/* Return: exits with -1 on error */ 385f08c3bdfSopenharmony_ci/* exits with a 0 on success. */ 386f08c3bdfSopenharmony_ci/* */ 387f08c3bdfSopenharmony_ci/******************************************************************************/ 388f08c3bdfSopenharmony_ciint main(int argc, /* number of input parameters. */ 389f08c3bdfSopenharmony_ci char **argv) 390f08c3bdfSopenharmony_ci{ /* pointer to the command line arguments. */ 391f08c3bdfSopenharmony_ci int c; /* command line options */ 392f08c3bdfSopenharmony_ci int num_iter; /* number of iteration to perform */ 393f08c3bdfSopenharmony_ci int thrd_ndx; /* index into the array of threads. */ 394f08c3bdfSopenharmony_ci double exec_time; /* period for which the test is executed */ 395f08c3bdfSopenharmony_ci void *status; /* exit status for light weight process */ 396f08c3bdfSopenharmony_ci int sig_ndx; /* index into signal handler structure. */ 397f08c3bdfSopenharmony_ci pthread_t thid[1000]; /* pids of process that will map/write/unmap */ 398f08c3bdfSopenharmony_ci long chld_args[3]; /* arguments to funcs execed by child process */ 399f08c3bdfSopenharmony_ci extern char *optarg; /* arguments passed to each option */ 400f08c3bdfSopenharmony_ci struct sigaction sigptr; /* set up signal, for interval timer */ 401f08c3bdfSopenharmony_ci 402f08c3bdfSopenharmony_ci static struct signal_info { 403f08c3bdfSopenharmony_ci int signum; /* signal number that hasto be handled */ 404f08c3bdfSopenharmony_ci char *signame; /* name of the signal to be handled. */ 405f08c3bdfSopenharmony_ci } sig_info[] = { 406f08c3bdfSopenharmony_ci { 407f08c3bdfSopenharmony_ci SIGHUP, "SIGHUP"}, { 408f08c3bdfSopenharmony_ci SIGINT, "SIGINT"}, { 409f08c3bdfSopenharmony_ci SIGQUIT, "SIGQUIT"}, { 410f08c3bdfSopenharmony_ci SIGABRT, "SIGABRT"}, { 411f08c3bdfSopenharmony_ci SIGBUS, "SIGBUS"}, { 412f08c3bdfSopenharmony_ci SIGSEGV, "SIGSEGV"}, { 413f08c3bdfSopenharmony_ci SIGALRM, "SIGALRM"}, { 414f08c3bdfSopenharmony_ci SIGUSR1, "SIGUSR1"}, { 415f08c3bdfSopenharmony_ci SIGUSR2, "SIGUSR2"}, { 416f08c3bdfSopenharmony_ci -1, "ENDSIG"} 417f08c3bdfSopenharmony_ci }; 418f08c3bdfSopenharmony_ci 419f08c3bdfSopenharmony_ci /* set up the default values */ 420f08c3bdfSopenharmony_ci num_iter = 1000; /* repeate map - write - unmap operation 1000 times */ 421f08c3bdfSopenharmony_ci exec_time = 24.0; /* minimum time period for which to run the tests */ 422f08c3bdfSopenharmony_ci 423f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, "h:l:x:")) != -1) { 424f08c3bdfSopenharmony_ci switch (c) { 425f08c3bdfSopenharmony_ci case 'h': 426f08c3bdfSopenharmony_ci usage(argv[0]); 427f08c3bdfSopenharmony_ci break; 428f08c3bdfSopenharmony_ci case 'l': /* number of times to loop in the thread function */ 429f08c3bdfSopenharmony_ci if ((num_iter = atoi(optarg)) == 0) 430f08c3bdfSopenharmony_ci num_iter = 1000; 431f08c3bdfSopenharmony_ci break; 432f08c3bdfSopenharmony_ci case 'x': /* time in hrs to run this test. */ 433f08c3bdfSopenharmony_ci if ((exec_time = atof(optarg)) == 0) 434f08c3bdfSopenharmony_ci exec_time = 24; 435f08c3bdfSopenharmony_ci break; 436f08c3bdfSopenharmony_ci default: 437f08c3bdfSopenharmony_ci usage(argv[0]); 438f08c3bdfSopenharmony_ci break; 439f08c3bdfSopenharmony_ci } 440f08c3bdfSopenharmony_ci } 441f08c3bdfSopenharmony_ci 442f08c3bdfSopenharmony_ci fprintf(stdout, 443f08c3bdfSopenharmony_ci "\n\n\nTest is set to run with the following parameters:\n" 444f08c3bdfSopenharmony_ci "\tDuration of test: [%f]hrs\n" 445f08c3bdfSopenharmony_ci "\tnumber of shmat shm detach: [%d]\n", exec_time, num_iter); 446f08c3bdfSopenharmony_ci 447f08c3bdfSopenharmony_ci /* set up signals */ 448f08c3bdfSopenharmony_ci sigptr.sa_handler = (void (*)(int signal))sig_handler; 449f08c3bdfSopenharmony_ci sigfillset(&sigptr.sa_mask); 450f08c3bdfSopenharmony_ci sigptr.sa_flags = SA_SIGINFO; 451f08c3bdfSopenharmony_ci for (sig_ndx = 0; sig_info[sig_ndx].signum != -1; sig_ndx++) { 452f08c3bdfSopenharmony_ci sigaddset(&sigptr.sa_mask, sig_info[sig_ndx].signum); 453f08c3bdfSopenharmony_ci if (sigaction(sig_info[sig_ndx].signum, &sigptr, 454f08c3bdfSopenharmony_ci NULL) == -1) { 455f08c3bdfSopenharmony_ci perror("man(): sigaction()"); 456f08c3bdfSopenharmony_ci fprintf(stderr, 457f08c3bdfSopenharmony_ci "could not set handler for SIGALRM, errno = %d\n", 458f08c3bdfSopenharmony_ci errno); 459f08c3bdfSopenharmony_ci exit(-1); 460f08c3bdfSopenharmony_ci } 461f08c3bdfSopenharmony_ci } 462f08c3bdfSopenharmony_ci 463f08c3bdfSopenharmony_ci chld_args[0] = num_iter; 464f08c3bdfSopenharmony_ci alarm(exec_time * 3600.00); 465f08c3bdfSopenharmony_ci 466f08c3bdfSopenharmony_ci for (;;) { 467f08c3bdfSopenharmony_ci /* create 3 threads */ 468f08c3bdfSopenharmony_ci if (pthread_create(&thid[0], NULL, shmat_shmdt, chld_args)) { 469f08c3bdfSopenharmony_ci perror("main(): pthread_create()"); 470f08c3bdfSopenharmony_ci exit(-1); 471f08c3bdfSopenharmony_ci } else { 472f08c3bdfSopenharmony_ci fprintf(stdout, 473f08c3bdfSopenharmony_ci "created thread id[%#lx], execs fn shmat_shmdt()\n", 474f08c3bdfSopenharmony_ci thid[0]); 475f08c3bdfSopenharmony_ci } 476f08c3bdfSopenharmony_ci sched_yield(); 477f08c3bdfSopenharmony_ci 478f08c3bdfSopenharmony_ci if (pthread_create(&thid[1], NULL, write_to_mem, chld_args)) { 479f08c3bdfSopenharmony_ci perror("main(): pthread_create()"); 480f08c3bdfSopenharmony_ci exit(-1); 481f08c3bdfSopenharmony_ci } else { 482f08c3bdfSopenharmony_ci fprintf(stdout, 483f08c3bdfSopenharmony_ci "created thread id[%#lx], execs fn write_to_mem()\n", 484f08c3bdfSopenharmony_ci thid[1]); 485f08c3bdfSopenharmony_ci } 486f08c3bdfSopenharmony_ci sched_yield(); 487f08c3bdfSopenharmony_ci 488f08c3bdfSopenharmony_ci if (pthread_create(&thid[2], NULL, read_from_mem, chld_args)) { 489f08c3bdfSopenharmony_ci perror("main(): pthread_create()"); 490f08c3bdfSopenharmony_ci exit(-1); 491f08c3bdfSopenharmony_ci } else { 492f08c3bdfSopenharmony_ci fprintf(stdout, 493f08c3bdfSopenharmony_ci "created thread id[%#lx], execs fn read_from_mem()\n", 494f08c3bdfSopenharmony_ci thid[2]); 495f08c3bdfSopenharmony_ci } 496f08c3bdfSopenharmony_ci sched_yield(); 497f08c3bdfSopenharmony_ci 498f08c3bdfSopenharmony_ci /* wait for the children to terminate */ 499f08c3bdfSopenharmony_ci for (thrd_ndx = 0; thrd_ndx < 3; thrd_ndx++) { 500f08c3bdfSopenharmony_ci if (pthread_join(thid[thrd_ndx], &status)) { 501f08c3bdfSopenharmony_ci perror("main(): pthread_create()"); 502f08c3bdfSopenharmony_ci exit(-1); 503f08c3bdfSopenharmony_ci } 504f08c3bdfSopenharmony_ci if (status == (void *)-1) { 505f08c3bdfSopenharmony_ci fprintf(stderr, 506f08c3bdfSopenharmony_ci "thread [%#lx] - process exited with errors %ld\n", 507f08c3bdfSopenharmony_ci thid[thrd_ndx], (long)status); 508f08c3bdfSopenharmony_ci exit(-1); 509f08c3bdfSopenharmony_ci } 510f08c3bdfSopenharmony_ci } 511f08c3bdfSopenharmony_ci } 512f08c3bdfSopenharmony_ci fprintf(stdout, "TEST PASSED\n"); 513f08c3bdfSopenharmony_ci return 0; 514f08c3bdfSopenharmony_ci} 515