📄 maptest.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * */#include <sys/types.h>#include <sys/mman.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>#include <sys/signal.h>#include <setjmp.h>#define MORSE#define NUM_STEPS 10#define FILE_SIZE 10*4096#define TEST(name) printf("TEST: "name" "); fflush(stdout);#define PROGRESS() printf("."); fflush(stdout);#define PASSED() printf(" PASSED\n");#define FAILED() printf(" FAILED\n");int check_buf(char *buf, int buf_size, char value);void set_buf(char *buf, int buf_size, char value);char *creat_buf(char *file_name, int buf_size);char *open_buf(char *file_name, int buf_size);char *cellfile(char *file_name, int cellid);void setup_sync_file(void);void sync_master(void);void sync_slave(void);int my_cellid;int other_cellid;volatile char *mysync;/* error handling */void die_on_sigbus(int value);void handle_sigbus(int value);jmp_buf return_addr;/* * PLACE TESTS HERE */void rdwr_test(void);void sync_test(void);void large_test(void);void trunc_test(void);typedef struct test { void (*func)(void); char command; char *helpstr;} test;test tests[] = { rdwr_test, 'r', "read/write test, single cell remote read/write test.", sync_test, 's', "sync test, tests the use of the syncfile.", large_test, 'l', "large test, tests mapping of file > 1 page.", trunc_test, 't', "truncation test, tests truncation of shared files."};#define NUM_TESTS (sizeof(tests)/sizeof(test))int main(int argc, char *argv[]){ int i; char *tests_to_run; if (argc != 4) { printf("Usage: %s tests this_cellid other_cellid \n", argv[0]); printf(" tests: a string of the following tests to run\n"); for (i=0; i<NUM_TESTS; i++) { printf(" %c - %s\n", tests[i].command, tests[i].helpstr); } printf(" Start the process on the cell will the lower ID first, then\n"); printf(" if applicable, start the process on the other cell.\n"); exit(-1); } signal(SIGBUS, die_on_sigbus); my_cellid = atoi(argv[2]); other_cellid = atoi(argv[3]); if ((my_cellid == other_cellid) || (my_cellid < 0) || (other_cellid < 0)) { printf("Error: bad cellid in args.\n"); exit(-1); } setup_sync_file(); printf("Starting tests from cell %d to cell %d.\n", my_cellid, other_cellid); printf("You can now start other process if applicable.\n"); for (tests_to_run = argv[1]; *tests_to_run; tests_to_run++) { for (i=0; i<NUM_TESTS; i++) { if (*tests_to_run == tests[i].command) { tests[i].func(); break; } } if (i == NUM_TESTS) { printf("Bad test '%c', ignoring.\n", *tests_to_run); } } return 0;}/* * */void setup_sync_file(void){ if (my_cellid < other_cellid) { mysync = creat_buf(cellfile("syncfile.tmp", my_cellid), 1); } else { mysync = open_buf(cellfile("syncfile.tmp", other_cellid), 1); } if (!mysync) { perror("Error opening syncfile"); exit(-1); }}void sync_master(void){ while (*mysync != 1) ; *mysync = 0;}void sync_slave(void){ if (*mysync == 1) { printf("Bad syncfile.\n"); exit(-1); } *mysync = 1; while (*mysync != 0) ; }/* * */void rdwr_test(void){ char *buf; int i; TEST("rdwr"); buf = open_buf(cellfile("rdwr.tmp", other_cellid), 16); if (!buf) { FAILED(); perror("rdwr"); exit(-1); } for (i=0; i<16; i++) { printf("%c", buf[i]); } for (i=0; i<16; i++) { buf[i] = 'a' + i; } PASSED(); }/* * */void sync_test(void){ TEST("sync"); if (my_cellid < other_cellid) { sync_master(); } else { sync_slave(); } PASSED();}/* * large_test */void large_master(void){ int step; char *buf; TEST("large_master"); buf = creat_buf(cellfile("simple.tmp", my_cellid), FILE_SIZE); if (!buf) { FAILED(); perror("large_master"); exit(-1); } PROGRESS(); set_buf(buf, FILE_SIZE, 0); sync_master(); for (step = 2; step < NUM_STEPS; step += 2) { while (!check_buf(buf, FILE_SIZE, (char)(step-1))) ; PROGRESS(); set_buf(buf, FILE_SIZE, (char)step); } PASSED();}void large_slave(void){ char *buf; int step; TEST("large_slave"); sync_slave(); buf = open_buf(cellfile("simple.tmp", other_cellid), FILE_SIZE); if (!buf) { FAILED(); perror("large_slave"); exit(-1); } for (step = 1; step < NUM_STEPS; step += 2) { while (!check_buf(buf, FILE_SIZE, (char)(step-1))) ; PROGRESS(); set_buf(buf, FILE_SIZE, (char)step); } PASSED();}void large_test(void){ if (my_cellid < other_cellid) { large_master(); large_slave(); } else { large_slave(); large_master(); }}/* * trunc_test */void trunc_master(void){ char *buf; int fd; TEST("trunc_master"); buf = creat_buf(cellfile("trunc.tmp", my_cellid), FILE_SIZE); if (!buf) { FAILED(); perror("trunc_master"); exit(-1); } PROGRESS(); set_buf(buf, FILE_SIZE, 0); sync_master(); while (!check_buf(buf, FILE_SIZE, 2)) ; PROGRESS(); fd = open(cellfile("trunc.tmp", my_cellid), O_RDWR|O_CREAT|O_TRUNC, 0777); if (fd < 0) { FAILED(); perror("trunc_master"); exit(-1); } PASSED();}void trunc_slave(void){ char *buf; TEST("trunc_slave"); sync_slave(); PROGRESS(); buf = open_buf(cellfile("trunc.tmp", other_cellid), FILE_SIZE); if (!buf) { FAILED(); perror("trunc_slave"); exit(-1); } signal(SIGBUS, handle_sigbus); if (setjmp(return_addr) == 0) { while (1) { set_buf(buf, FILE_SIZE, 2); } } signal(SIGBUS, die_on_sigbus); PASSED();}void trunc_test(void){ if (my_cellid < other_cellid) { trunc_master(); trunc_slave(); } else { trunc_slave(); trunc_master(); } }/* * utilities */char *creat_buf(char *file_name, int buf_size){ int fd; char *buf; fd = open(file_name, O_RDWR|O_CREAT|O_TRUNC, 0777); if (fd < 0) { return 0; } if (lseek(fd, buf_size-1, SEEK_SET) != (buf_size-1)) { close(fd); return 0; } if (write(fd, "\000", 1) != 1) { close(fd); return 0; } buf = (char *)mmap(0, (unsigned int)buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (buf == (char *)-1) { close(fd); return 0; } return buf;}char *open_buf(char *file_name, int buf_size){ int fd; char *buf; fd = open(file_name, O_RDWR); if (fd < 0) { return 0; } buf = (char *)mmap(0, (unsigned int)buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (buf == (char *)-1) { close(fd); return 0; } return buf;}int check_buf(char *buf, int buf_size, char value){ int i, rv = 1; for (i=0; i<buf_size; i++) { if (buf[i] != value) { rv = 0; } } return rv;}void set_buf(char *buf, int buf_size, char value){ int i; for (i=0; i<buf_size; i++) { buf[i] = value; }}char tmpbuf[256];#ifdef MORSE#define FORMAT ",cell%d,%s"#else#define FORMAT "/cell%d/%s"#endifchar *cellfile(char *file_name, int cellid){ sprintf(tmpbuf, FORMAT, cellid, file_name); return tmpbuf;}void die_on_sigbus(int value){ perror("SIG BUS"); exit(-1);}void handle_sigbus(int value){ sigrelse(SIGBUS); longjmp(return_addr, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -