1f08c3bdfSopenharmony_ci/* IBM Corporation */ 2f08c3bdfSopenharmony_ci/* 01/02/2003 Port to LTP avenakt@us.ibm.com */ 3f08c3bdfSopenharmony_ci/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 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#define _GNU_SOURCE 1 21f08c3bdfSopenharmony_ci#include <sys/types.h> 22f08c3bdfSopenharmony_ci#include <stdio.h> 23f08c3bdfSopenharmony_ci#include <fcntl.h> 24f08c3bdfSopenharmony_ci#include <signal.h> 25f08c3bdfSopenharmony_ci#include <sys/mman.h> 26f08c3bdfSopenharmony_ci#include <sys/wait.h> 27f08c3bdfSopenharmony_ci#include <sys/stat.h> 28f08c3bdfSopenharmony_ci#include <unistd.h> 29f08c3bdfSopenharmony_ci#include <errno.h> 30f08c3bdfSopenharmony_ci/***** LTP Port *****/ 31f08c3bdfSopenharmony_ci#include "test.h" 32f08c3bdfSopenharmony_ci#define FAILED 0 33f08c3bdfSopenharmony_ci#define PASSED 1 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ciint local_flag = PASSED; 36f08c3bdfSopenharmony_cichar *TCID = "mmapstress09"; 37f08c3bdfSopenharmony_ciFILE *temp; 38f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ciint anyfail(); 41f08c3bdfSopenharmony_civoid ok_exit(); 42f08c3bdfSopenharmony_ci/***** ** ** *****/ 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci/* 45f08c3bdfSopenharmony_ci * This test is mostly duplicated from the tmmap test, but tests 46f08c3bdfSopenharmony_ci * stress tests anonymous maps. It forks a specified number of children, 47f08c3bdfSopenharmony_ci * who inherit an anonymous shared map, and who, make a given number of 48f08c3bdfSopenharmony_ci * accesses to random pages in the map (reading & writing and comparing data). 49f08c3bdfSopenharmony_ci * Then the child exits and the parent forks another to take its place. 50f08c3bdfSopenharmony_ci * The test fails if a child sees incorrect data. 51f08c3bdfSopenharmony_ci * 52f08c3bdfSopenharmony_ci * This program continues to run until it either receives a SIGINT, 53f08c3bdfSopenharmony_ci * or times out (if a timeout value is specified). When either of 54f08c3bdfSopenharmony_ci * these things happens, it cleans up its kids, then checks 55f08c3bdfSopenharmony_ci * the map to make sure it has the correct data. 56f08c3bdfSopenharmony_ci * 57f08c3bdfSopenharmony_ci * usage: 58f08c3bdfSopenharmony_ci * mmapstress09 -p nprocs [-t minutes -s mapsize -m msync -r -d] 59f08c3bdfSopenharmony_ci * 60f08c3bdfSopenharmony_ci * where: 61f08c3bdfSopenharmony_ci * -p nprocs - specifies the number of mapping children 62f08c3bdfSopenharmony_ci * to create. (nprocs + 1 children actually 63f08c3bdfSopenharmony_ci * get created, since one is the writer child) 64f08c3bdfSopenharmony_ci * -t minutes - specifies minutes to run. If not specified, 65f08c3bdfSopenharmony_ci * default is to run forever until a SIGINT 66f08c3bdfSopenharmony_ci * is received. 67f08c3bdfSopenharmony_ci * -s mapsize - mapsize (defaults to MAPSIZE) 68f08c3bdfSopenharmony_ci * -m - do msyncs 69f08c3bdfSopenharmony_ci * -r - randomize number of pages map children check. 70f08c3bdfSopenharmony_ci * (random % MAXLOOPS). If not specified, each 71f08c3bdfSopenharmony_ci * child checks MAXLOOPS pages. 72f08c3bdfSopenharmony_ci * -d - enable debug outputd 73f08c3bdfSopenharmony_ci */ 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci#define MAXLOOPS 500 /* max pages for map children to write */ 76f08c3bdfSopenharmony_ci#define MAPSIZE (64*1024) /* default mapsize set up by parent */ 77f08c3bdfSopenharmony_ci#ifdef roundup 78f08c3bdfSopenharmony_ci#undef roundup 79f08c3bdfSopenharmony_ci#endif 80f08c3bdfSopenharmony_ci#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ciextern time_t time(time_t *); 83f08c3bdfSopenharmony_ciextern char *ctime(const time_t *); 84f08c3bdfSopenharmony_ciextern void *malloc(size_t); 85f08c3bdfSopenharmony_ciextern void exit(int); 86f08c3bdfSopenharmony_ciextern long lrand48(void); 87f08c3bdfSopenharmony_ciextern void srand(unsigned); 88f08c3bdfSopenharmony_ciextern void srand48(long); 89f08c3bdfSopenharmony_ciextern int rand(void); 90f08c3bdfSopenharmony_ciextern int atoi(const char *); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_citypedef unsigned char uchar_t; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_cichar *usage = "-p nprocs [-t minutes -s mapsize -m -r -d]"; 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ciunsigned int initrand(void); 97f08c3bdfSopenharmony_civoid finish(int sig); 98f08c3bdfSopenharmony_civoid child_mapper(unsigned procno, unsigned nprocs); 99f08c3bdfSopenharmony_ciint mapokay(uchar_t * expbuf); 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ciint finished = 0; 102f08c3bdfSopenharmony_ciint debug = 0; 103f08c3bdfSopenharmony_ciint mapsize = MAPSIZE; 104f08c3bdfSopenharmony_ciunsigned mappages; 105f08c3bdfSopenharmony_ciint pagesize; 106f08c3bdfSopenharmony_ciunsigned randloops = 0; 107f08c3bdfSopenharmony_ciunsigned dosync = 0; 108f08c3bdfSopenharmony_ciunsigned pattern = 0; 109f08c3bdfSopenharmony_cicaddr_t mapaddr; 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 112f08c3bdfSopenharmony_ci{ 113f08c3bdfSopenharmony_ci char *progname; 114f08c3bdfSopenharmony_ci unsigned c; 115f08c3bdfSopenharmony_ci extern char *optarg; 116f08c3bdfSopenharmony_ci unsigned nprocs = 0; 117f08c3bdfSopenharmony_ci unsigned procno; 118f08c3bdfSopenharmony_ci pid_t *pidarray = NULL; 119f08c3bdfSopenharmony_ci pid_t pid; 120f08c3bdfSopenharmony_ci uchar_t *buf, *ptr; 121f08c3bdfSopenharmony_ci unsigned int seed; 122f08c3bdfSopenharmony_ci float alarmtime = 0; 123f08c3bdfSopenharmony_ci struct sigaction sa; 124f08c3bdfSopenharmony_ci unsigned i, j; 125f08c3bdfSopenharmony_ci uchar_t data; 126f08c3bdfSopenharmony_ci int no_prob = 0; 127f08c3bdfSopenharmony_ci time_t t; 128f08c3bdfSopenharmony_ci int wait_stat; 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci progname = *argv; 131f08c3bdfSopenharmony_ci pagesize = sysconf(_SC_PAGE_SIZE); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci if (argc < 2) { 134f08c3bdfSopenharmony_ci (void)fprintf(stderr, "usage: %s %s\n", progname, usage); 135f08c3bdfSopenharmony_ci anyfail(); 136f08c3bdfSopenharmony_ci } 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, "mdrp:t:s:")) != -1) { 139f08c3bdfSopenharmony_ci switch (c) { 140f08c3bdfSopenharmony_ci case 'd': 141f08c3bdfSopenharmony_ci debug = 1; 142f08c3bdfSopenharmony_ci break; 143f08c3bdfSopenharmony_ci case 't': 144f08c3bdfSopenharmony_ci alarmtime = atof(optarg) * 60; 145f08c3bdfSopenharmony_ci break; 146f08c3bdfSopenharmony_ci case 'p': 147f08c3bdfSopenharmony_ci nprocs = atoi(optarg); 148f08c3bdfSopenharmony_ci break; 149f08c3bdfSopenharmony_ci case 'm': 150f08c3bdfSopenharmony_ci dosync = 1; 151f08c3bdfSopenharmony_ci break; 152f08c3bdfSopenharmony_ci case 's': 153f08c3bdfSopenharmony_ci mapsize = atoi(optarg); 154f08c3bdfSopenharmony_ci if (mapsize < 0) { 155f08c3bdfSopenharmony_ci (void)fprintf(stderr, "error: negative " 156f08c3bdfSopenharmony_ci "mapsize\n"); 157f08c3bdfSopenharmony_ci anyfail(); 158f08c3bdfSopenharmony_ci } 159f08c3bdfSopenharmony_ci break; 160f08c3bdfSopenharmony_ci case 'r': 161f08c3bdfSopenharmony_ci randloops = 1; 162f08c3bdfSopenharmony_ci break; 163f08c3bdfSopenharmony_ci default: 164f08c3bdfSopenharmony_ci (void)fprintf(stderr, "usage: %s %s\n", progname, 165f08c3bdfSopenharmony_ci usage); 166f08c3bdfSopenharmony_ci anyfail(); 167f08c3bdfSopenharmony_ci } 168f08c3bdfSopenharmony_ci } 169f08c3bdfSopenharmony_ci 170f08c3bdfSopenharmony_ci /* nprocs is unsigned */ 171f08c3bdfSopenharmony_ci if (nprocs > 255) { 172f08c3bdfSopenharmony_ci (void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n", 173f08c3bdfSopenharmony_ci nprocs); 174f08c3bdfSopenharmony_ci anyfail(); 175f08c3bdfSopenharmony_ci } 176f08c3bdfSopenharmony_ci (void)time(&t); 177f08c3bdfSopenharmony_ci// (void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ci seed = initrand(); 180f08c3bdfSopenharmony_ci pattern = seed & 0xff; 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_ci if (debug) { 183f08c3bdfSopenharmony_ci (void)printf("%s mapsize %d bytes, pattern %d\n", 184f08c3bdfSopenharmony_ci progname, mapsize, pattern); 185f08c3bdfSopenharmony_ci if (alarmtime) 186f08c3bdfSopenharmony_ci (void)printf("running for %f minutes\n", 187f08c3bdfSopenharmony_ci alarmtime / 60); 188f08c3bdfSopenharmony_ci else 189f08c3bdfSopenharmony_ci (void)printf("running with no time limit\n"); 190f08c3bdfSopenharmony_ci } 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci if ((mapaddr = mmap(0, mapsize, PROT_READ | PROT_WRITE, 193f08c3bdfSopenharmony_ci MAP_ANONYMOUS | MAP_SHARED, 0, 0)) 194f08c3bdfSopenharmony_ci == (caddr_t) - 1) { 195f08c3bdfSopenharmony_ci perror("mmap error"); 196f08c3bdfSopenharmony_ci anyfail(); 197f08c3bdfSopenharmony_ci } 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci if ((buf = malloc(pagesize)) == NULL 200f08c3bdfSopenharmony_ci || (pidarray = malloc(nprocs * sizeof(pid_t))) == NULL) { 201f08c3bdfSopenharmony_ci perror("malloc error"); 202f08c3bdfSopenharmony_ci anyfail(); 203f08c3bdfSopenharmony_ci } 204f08c3bdfSopenharmony_ci 205f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 206f08c3bdfSopenharmony_ci *(pidarray + i) = 0; 207f08c3bdfSopenharmony_ci 208f08c3bdfSopenharmony_ci /* 209f08c3bdfSopenharmony_ci * Initialize page compare buffer, then initialize map. 210f08c3bdfSopenharmony_ci */ 211f08c3bdfSopenharmony_ci 212f08c3bdfSopenharmony_ci for (i = 0, data = 0; i < pagesize; i++) { 213f08c3bdfSopenharmony_ci *(buf + i) = (data + pattern) & 0xff; 214f08c3bdfSopenharmony_ci if (++data == nprocs) 215f08c3bdfSopenharmony_ci data = 0; 216f08c3bdfSopenharmony_ci } 217f08c3bdfSopenharmony_ci 218f08c3bdfSopenharmony_ci mappages = roundup(mapsize, pagesize) / pagesize; 219f08c3bdfSopenharmony_ci ptr = (uchar_t *) mapaddr; 220f08c3bdfSopenharmony_ci 221f08c3bdfSopenharmony_ci for (i = 0; i < mappages; i++) { 222f08c3bdfSopenharmony_ci for (j = 0; j < pagesize; j++) 223f08c3bdfSopenharmony_ci *ptr++ = *(buf + j); 224f08c3bdfSopenharmony_ci } 225f08c3bdfSopenharmony_ci 226f08c3bdfSopenharmony_ci /* 227f08c3bdfSopenharmony_ci * Fork off mmap children. 228f08c3bdfSopenharmony_ci */ 229f08c3bdfSopenharmony_ci for (procno = 0; procno < nprocs; procno++) { 230f08c3bdfSopenharmony_ci switch (pid = fork()) { 231f08c3bdfSopenharmony_ci 232f08c3bdfSopenharmony_ci case -1: 233f08c3bdfSopenharmony_ci perror("fork error"); 234f08c3bdfSopenharmony_ci goto cleanup; 235f08c3bdfSopenharmony_ci 236f08c3bdfSopenharmony_ci case 0: 237f08c3bdfSopenharmony_ci child_mapper(procno, nprocs); 238f08c3bdfSopenharmony_ci exit(0); 239f08c3bdfSopenharmony_ci 240f08c3bdfSopenharmony_ci default: 241f08c3bdfSopenharmony_ci pidarray[procno] = pid; 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci } 244f08c3bdfSopenharmony_ci 245f08c3bdfSopenharmony_ci /* 246f08c3bdfSopenharmony_ci * Plan for death by signal. User may have specified 247f08c3bdfSopenharmony_ci * a time limit, in which set an alarm and catch SIGALRM. 248f08c3bdfSopenharmony_ci * Also catch and cleanup with SIGINT. 249f08c3bdfSopenharmony_ci */ 250f08c3bdfSopenharmony_ci sa.sa_handler = finish; 251f08c3bdfSopenharmony_ci sa.sa_flags = 0; 252f08c3bdfSopenharmony_ci if (sigemptyset(&sa.sa_mask)) { 253f08c3bdfSopenharmony_ci perror("sigemptyset error"); 254f08c3bdfSopenharmony_ci goto cleanup; 255f08c3bdfSopenharmony_ci } 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_ci if (sigaction(SIGINT, &sa, 0) == -1) { 258f08c3bdfSopenharmony_ci perror("sigaction error"); 259f08c3bdfSopenharmony_ci goto cleanup; 260f08c3bdfSopenharmony_ci } 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci if (alarmtime) { 263f08c3bdfSopenharmony_ci if (sigaction(SIGALRM, &sa, 0) == -1) { 264f08c3bdfSopenharmony_ci perror("sigaction error"); 265f08c3bdfSopenharmony_ci goto cleanup; 266f08c3bdfSopenharmony_ci } 267f08c3bdfSopenharmony_ci (void)alarm(alarmtime); 268f08c3bdfSopenharmony_ci } 269f08c3bdfSopenharmony_ci 270f08c3bdfSopenharmony_ci /* 271f08c3bdfSopenharmony_ci * Now wait for children and refork them as needed. 272f08c3bdfSopenharmony_ci */ 273f08c3bdfSopenharmony_ci 274f08c3bdfSopenharmony_ci while (!finished) { 275f08c3bdfSopenharmony_ci do { 276f08c3bdfSopenharmony_ci pid = wait(&wait_stat); 277f08c3bdfSopenharmony_ci } while (pid == -1 && errno == EINTR); 278f08c3bdfSopenharmony_ci /* 279f08c3bdfSopenharmony_ci * Block signals while processing child exit. 280f08c3bdfSopenharmony_ci */ 281f08c3bdfSopenharmony_ci 282f08c3bdfSopenharmony_ci if (sighold(SIGALRM) || sighold(SIGINT)) { 283f08c3bdfSopenharmony_ci perror("sighold error"); 284f08c3bdfSopenharmony_ci goto cleanup; 285f08c3bdfSopenharmony_ci } 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci if (pid != -1) { 288f08c3bdfSopenharmony_ci /* 289f08c3bdfSopenharmony_ci * Check exit status, then refork with the 290f08c3bdfSopenharmony_ci * appropriate procno. 291f08c3bdfSopenharmony_ci */ 292f08c3bdfSopenharmony_ci if (!WIFEXITED(wait_stat) 293f08c3bdfSopenharmony_ci || WEXITSTATUS(wait_stat) != 0) { 294f08c3bdfSopenharmony_ci (void)fprintf(stderr, "child exit with err " 295f08c3bdfSopenharmony_ci "<x%x>\n", wait_stat); 296f08c3bdfSopenharmony_ci goto cleanup; 297f08c3bdfSopenharmony_ci } 298f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 299f08c3bdfSopenharmony_ci if (pid == pidarray[i]) 300f08c3bdfSopenharmony_ci break; 301f08c3bdfSopenharmony_ci if (i == nprocs) { 302f08c3bdfSopenharmony_ci (void)fprintf(stderr, 303f08c3bdfSopenharmony_ci "unknown child pid %d, <x%x>\n", 304f08c3bdfSopenharmony_ci pid, wait_stat); 305f08c3bdfSopenharmony_ci goto cleanup; 306f08c3bdfSopenharmony_ci } 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_ci if ((pid = fork()) == -1) { 309f08c3bdfSopenharmony_ci perror("fork error"); 310f08c3bdfSopenharmony_ci pidarray[i] = 0; 311f08c3bdfSopenharmony_ci goto cleanup; 312f08c3bdfSopenharmony_ci } else if (pid == 0) { /* child */ 313f08c3bdfSopenharmony_ci child_mapper(i, nprocs); 314f08c3bdfSopenharmony_ci exit(0); 315f08c3bdfSopenharmony_ci } else 316f08c3bdfSopenharmony_ci pidarray[i] = pid; 317f08c3bdfSopenharmony_ci } else { 318f08c3bdfSopenharmony_ci /* 319f08c3bdfSopenharmony_ci * wait returned an error. If EINTR, then 320f08c3bdfSopenharmony_ci * normal finish, else it's an unexpected 321f08c3bdfSopenharmony_ci * error... 322f08c3bdfSopenharmony_ci */ 323f08c3bdfSopenharmony_ci if (errno != EINTR || !finished) { 324f08c3bdfSopenharmony_ci perror("unexpected wait error"); 325f08c3bdfSopenharmony_ci goto cleanup; 326f08c3bdfSopenharmony_ci } 327f08c3bdfSopenharmony_ci } 328f08c3bdfSopenharmony_ci if (sigrelse(SIGALRM) || sigrelse(SIGINT)) { 329f08c3bdfSopenharmony_ci perror("sigrelse error"); 330f08c3bdfSopenharmony_ci goto cleanup; 331f08c3bdfSopenharmony_ci } 332f08c3bdfSopenharmony_ci } 333f08c3bdfSopenharmony_ci 334f08c3bdfSopenharmony_ci /* 335f08c3bdfSopenharmony_ci * Finished! Check the map for sanity, then kill all 336f08c3bdfSopenharmony_ci * the children and done!. 337f08c3bdfSopenharmony_ci */ 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci if (sighold(SIGALRM)) { 340f08c3bdfSopenharmony_ci perror("sighold error"); 341f08c3bdfSopenharmony_ci goto cleanup; 342f08c3bdfSopenharmony_ci } 343f08c3bdfSopenharmony_ci (void)alarm(0); 344f08c3bdfSopenharmony_ci no_prob = 1; 345f08c3bdfSopenharmony_ci 346f08c3bdfSopenharmony_cicleanup: 347f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 348f08c3bdfSopenharmony_ci (void)kill(pidarray[i], SIGKILL); /* failure? oh well. */ 349f08c3bdfSopenharmony_ci 350f08c3bdfSopenharmony_ci while (wait(&wait_stat) != -1 || errno != ECHILD) 351f08c3bdfSopenharmony_ci continue; 352f08c3bdfSopenharmony_ci 353f08c3bdfSopenharmony_ci if (no_prob) { /* only check file if no errors */ 354f08c3bdfSopenharmony_ci if (!mapokay(buf)) { 355f08c3bdfSopenharmony_ci (void)fprintf(stderr, "map data incorrect!\n"); 356f08c3bdfSopenharmony_ci anyfail(); 357f08c3bdfSopenharmony_ci } else 358f08c3bdfSopenharmony_ci (void)printf("map data okay\n"); 359f08c3bdfSopenharmony_ci } 360f08c3bdfSopenharmony_ci 361f08c3bdfSopenharmony_ci (void)time(&t); 362f08c3bdfSopenharmony_ci// (void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP POrt 363f08c3bdfSopenharmony_ci ok_exit(); 364f08c3bdfSopenharmony_ci tst_exit(); 365f08c3bdfSopenharmony_ci} 366f08c3bdfSopenharmony_ci 367f08c3bdfSopenharmony_ci/* 368f08c3bdfSopenharmony_ci * Child process that reads/writes map. The child reads/writes 369f08c3bdfSopenharmony_ci * its own locations on random pages of the map (its locations being 370f08c3bdfSopenharmony_ci * determined based on nprocs & procno). After a specific number of 371f08c3bdfSopenharmony_ci * iterations, it exits. 372f08c3bdfSopenharmony_ci */ 373f08c3bdfSopenharmony_civoid child_mapper(unsigned procno, unsigned nprocs) 374f08c3bdfSopenharmony_ci{ 375f08c3bdfSopenharmony_ci uchar_t *paddr; 376f08c3bdfSopenharmony_ci unsigned randpage; 377f08c3bdfSopenharmony_ci unsigned int seed; 378f08c3bdfSopenharmony_ci unsigned loopcnt; 379f08c3bdfSopenharmony_ci unsigned nloops; 380f08c3bdfSopenharmony_ci unsigned i; 381f08c3bdfSopenharmony_ci 382f08c3bdfSopenharmony_ci seed = initrand(); /* initialize random seed */ 383f08c3bdfSopenharmony_ci 384f08c3bdfSopenharmony_ci nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS; 385f08c3bdfSopenharmony_ci 386f08c3bdfSopenharmony_ci if (debug) 387f08c3bdfSopenharmony_ci (void)printf("child %d (pid %d): seed %d, loop %d\n", 388f08c3bdfSopenharmony_ci procno, getpid(), seed, nloops); 389f08c3bdfSopenharmony_ci 390f08c3bdfSopenharmony_ci /* 391f08c3bdfSopenharmony_ci * Now loop read/writing random pages. 392f08c3bdfSopenharmony_ci */ 393f08c3bdfSopenharmony_ci 394f08c3bdfSopenharmony_ci for (loopcnt = 0; loopcnt < nloops; loopcnt++) { 395f08c3bdfSopenharmony_ci randpage = lrand48() % mappages; 396f08c3bdfSopenharmony_ci /* find the page address */ 397f08c3bdfSopenharmony_ci paddr = (uchar_t *) (mapaddr + (randpage * pagesize)); 398f08c3bdfSopenharmony_ci 399f08c3bdfSopenharmony_ci for (i = procno; i < pagesize; i += nprocs) { 400f08c3bdfSopenharmony_ci if (*((unsigned char *)(paddr + i)) 401f08c3bdfSopenharmony_ci != ((procno + pattern) & 0xff)) { 402f08c3bdfSopenharmony_ci (void)fprintf(stderr, 403f08c3bdfSopenharmony_ci "child %d: invalid data <x%x>", 404f08c3bdfSopenharmony_ci procno, 405f08c3bdfSopenharmony_ci *((unsigned char *)(paddr + i))); 406f08c3bdfSopenharmony_ci (void)fprintf(stderr, 407f08c3bdfSopenharmony_ci " at pg %d off %d, exp <x%x>\n", 408f08c3bdfSopenharmony_ci randpage, i, 409f08c3bdfSopenharmony_ci (procno + pattern) & 0xff); 410f08c3bdfSopenharmony_ci anyfail(); 411f08c3bdfSopenharmony_ci } 412f08c3bdfSopenharmony_ci /* 413f08c3bdfSopenharmony_ci * Now write it. 414f08c3bdfSopenharmony_ci */ 415f08c3bdfSopenharmony_ci 416f08c3bdfSopenharmony_ci *(paddr + i) = (procno + pattern) & 0xff; 417f08c3bdfSopenharmony_ci } 418f08c3bdfSopenharmony_ci } 419f08c3bdfSopenharmony_ci 420f08c3bdfSopenharmony_ci if (dosync) { 421f08c3bdfSopenharmony_ci randpage = (unsigned)lrand48() % mappages; 422f08c3bdfSopenharmony_ci paddr = (uchar_t *) mapaddr + (randpage * pagesize); 423f08c3bdfSopenharmony_ci if (msync((caddr_t) paddr, (mappages - randpage) * pagesize, 424f08c3bdfSopenharmony_ci MS_SYNC) == -1) { 425f08c3bdfSopenharmony_ci perror("msync error"); 426f08c3bdfSopenharmony_ci anyfail(); 427f08c3bdfSopenharmony_ci } 428f08c3bdfSopenharmony_ci } 429f08c3bdfSopenharmony_ci 430f08c3bdfSopenharmony_ci exit(0); 431f08c3bdfSopenharmony_ci} 432f08c3bdfSopenharmony_ci 433f08c3bdfSopenharmony_ci/* 434f08c3bdfSopenharmony_ci * Make sure file has all the correct data. 435f08c3bdfSopenharmony_ci */ 436f08c3bdfSopenharmony_ciint mapokay(uchar_t * expbuf) 437f08c3bdfSopenharmony_ci{ 438f08c3bdfSopenharmony_ci uchar_t *ptr; 439f08c3bdfSopenharmony_ci unsigned i, j; 440f08c3bdfSopenharmony_ci 441f08c3bdfSopenharmony_ci ptr = (uchar_t *) mapaddr; 442f08c3bdfSopenharmony_ci for (i = 0; i < mappages; i++) { 443f08c3bdfSopenharmony_ci /* 444f08c3bdfSopenharmony_ci * Compare read bytes of data. 445f08c3bdfSopenharmony_ci */ 446f08c3bdfSopenharmony_ci for (j = 0; j < pagesize; j++) { 447f08c3bdfSopenharmony_ci if (*ptr != expbuf[j]) { 448f08c3bdfSopenharmony_ci (void)fprintf(stderr, 449f08c3bdfSopenharmony_ci "bad map data: exp %c got %c)", 450f08c3bdfSopenharmony_ci expbuf[j], *ptr); 451f08c3bdfSopenharmony_ci (void)fprintf(stderr, ", pg %d off %d\n", i, j); 452f08c3bdfSopenharmony_ci anyfail(); 453f08c3bdfSopenharmony_ci } 454f08c3bdfSopenharmony_ci ptr++; 455f08c3bdfSopenharmony_ci } 456f08c3bdfSopenharmony_ci } 457f08c3bdfSopenharmony_ci 458f08c3bdfSopenharmony_ci return 1; 459f08c3bdfSopenharmony_ci} 460f08c3bdfSopenharmony_ci 461f08c3bdfSopenharmony_ci /*ARGSUSED*/ void finish(int sig) 462f08c3bdfSopenharmony_ci{ 463f08c3bdfSopenharmony_ci finished++; 464f08c3bdfSopenharmony_ci return; 465f08c3bdfSopenharmony_ci} 466f08c3bdfSopenharmony_ci 467f08c3bdfSopenharmony_ciunsigned int initrand(void) 468f08c3bdfSopenharmony_ci{ 469f08c3bdfSopenharmony_ci unsigned int seed; 470f08c3bdfSopenharmony_ci 471f08c3bdfSopenharmony_ci /* 472f08c3bdfSopenharmony_ci * Initialize random seed... Got this from a test written 473f08c3bdfSopenharmony_ci * by scooter: 474f08c3bdfSopenharmony_ci * Use srand/rand to diffuse the information from the 475f08c3bdfSopenharmony_ci * time and pid. If you start several processes, then 476f08c3bdfSopenharmony_ci * the time and pid information don't provide much 477f08c3bdfSopenharmony_ci * variation. 478f08c3bdfSopenharmony_ci */ 479f08c3bdfSopenharmony_ci srand((unsigned int)getpid()); 480f08c3bdfSopenharmony_ci seed = rand(); 481f08c3bdfSopenharmony_ci srand((unsigned int)time(NULL)); 482f08c3bdfSopenharmony_ci seed = (seed ^ rand()) % 100000; 483f08c3bdfSopenharmony_ci srand48((long int)seed); 484f08c3bdfSopenharmony_ci return (seed); 485f08c3bdfSopenharmony_ci} 486f08c3bdfSopenharmony_ci 487f08c3bdfSopenharmony_ci/***** LTP Port *****/ 488f08c3bdfSopenharmony_civoid ok_exit(void) 489f08c3bdfSopenharmony_ci{ 490f08c3bdfSopenharmony_ci tst_resm(TPASS, "Test passed"); 491f08c3bdfSopenharmony_ci tst_exit(); 492f08c3bdfSopenharmony_ci} 493f08c3bdfSopenharmony_ci 494f08c3bdfSopenharmony_ciint anyfail(void) 495f08c3bdfSopenharmony_ci{ 496f08c3bdfSopenharmony_ci tst_brkm(TFAIL, NULL, "Test failed"); 497f08c3bdfSopenharmony_ci} 498f08c3bdfSopenharmony_ci 499f08c3bdfSopenharmony_ci/***** ** ** *****/ 500