1 /* 2 * Copyright (c) 2005, Bull S.A.. All rights reserved. 3 * Created by: Sebastien Decugis 4 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 17 * This stress test aims to test the following assertion: 18 * sem_getvalue always returns the value of the semaphore at a given time 19 * during the call into the sval argument. 20 21 * The steps are: 22 * -> Create a named semaphore and an unnamed semaphore, initialized to 0. 23 * -> create two threads which continuously post and wait these semaphores. 24 * -> main loops on sem_getvalue on these two semaphores. 25 26 * The test fails if sem_getvalue gets a value different from 0 or 1. 27 28 */ 29 30 #include <pthread.h> 31 #include <stdarg.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <unistd.h> 36 37 #include <semaphore.h> 38 #include <fcntl.h> 39 #include <errno.h> 40 #include <signal.h> 41 42 #include "testfrmw.h" 43 #include "testfrmw.c" 44 /* This header is responsible for defining the following macros: 45 * UNRESOLVED(ret, descr); 46 * where descr is a description of the error and ret is an int (error code for example) 47 * FAILED(descr); 48 * where descr is a short text saying why the test has failed. 49 * PASSED(); 50 * No parameter. 51 * 52 * Both three macros shall terminate the calling process. 53 * The testcase shall not terminate in any other maneer. 54 * 55 * The other file defines the functions 56 * void output_init() 57 * void output(char * string, ...) 58 * 59 * Those may be used to output information. 60 */ 61 62 #ifndef VERBOSE 63 #define VERBOSE 1 64 #endif 65 66 #define SEM_NAME "/set_getval_stress" 67 68 #define INIT_VAL 0 69 70 char do_it = 1; 71 long long iterations = 0; 72 73 /* Handler for user request to terminate */ 74 void sighdl(int sig) 75 { 76 /* do_it = 0 */ 77 78 do { 79 do_it = 0; 80 } while (do_it); 81 } 82 83 /* Thread function */ 84 void *threaded(void *arg) 85 { 86 int ret = 0; 87 88 do { 89 /* sem_post */ 90 ret = sem_post(arg); 91 92 if (ret != 0) { 93 UNRESOLVED(errno, "Failed to post the semaphore"); 94 } 95 96 /* sem wait */ 97 do { 98 ret = sem_wait(arg); 99 } while ((ret != 0) && (errno == EINTR)); 100 101 if (ret != 0) { 102 UNRESOLVED(errno, "Failed to wait for the semaphore"); 103 } 104 105 } while (do_it); 106 107 return NULL; 108 } 109 110 /* Main function */ 111 int main(int argc, char *argv[]) 112 { 113 int ret = 0, value; 114 115 struct sigaction sa; 116 117 pthread_t child1, child2; 118 119 sem_t unnamed, *named; 120 121 /* Initialize output routine */ 122 output_init(); 123 124 /* Register the signal handler for SIGUSR1 */ 125 sigemptyset(&sa.sa_mask); 126 127 sa.sa_flags = 0; 128 129 sa.sa_handler = sighdl; 130 131 if ((ret = sigaction(SIGUSR1, &sa, NULL))) { 132 UNRESOLVED(ret, "Unable to register signal handler"); 133 } 134 135 if ((ret = sigaction(SIGALRM, &sa, NULL))) { 136 UNRESOLVED(ret, "Unable to register signal handler"); 137 } 138 #if VERBOSE > 1 139 output("[parent] Signal handler registered\n"); 140 141 #endif 142 143 /* Initialize the semaphores */ 144 named = sem_open(SEM_NAME, O_CREAT, 0777, INIT_VAL); 145 146 if (named == SEM_FAILED) { 147 UNRESOLVED(errno, "Failed to sem_open"); 148 } 149 150 ret = sem_unlink(SEM_NAME); 151 152 if (ret != 0) { 153 UNRESOLVED(errno, "Failed to sem_unlink"); 154 } 155 156 ret = sem_init(&unnamed, 0, INIT_VAL); 157 158 if (ret != 0) { 159 UNRESOLVED(errno, "Failed to sem_init"); 160 } 161 162 /* Create the threads */ 163 ret = pthread_create(&child1, NULL, threaded, named); 164 165 if (ret != 0) { 166 UNRESOLVED(ret, "Failed to create a thread"); 167 } 168 169 ret = pthread_create(&child2, NULL, threaded, &unnamed); 170 171 if (ret != 0) { 172 UNRESOLVED(ret, "Failed to create a thread"); 173 } 174 175 /* loop */ 176 while (do_it) { 177 ret = sem_getvalue(named, &value); 178 179 if (ret != 0) { 180 UNRESOLVED(errno, "Failed to get sem value"); 181 } 182 183 if ((value != INIT_VAL) && (value != INIT_VAL + 1)) { 184 output("Got value %d, expected %d or %d only\n", 185 value, INIT_VAL, INIT_VAL + 1); 186 FAILED 187 ("sem_getvalue returned an invalid value for the named semaphore"); 188 } 189 190 ret = sem_getvalue(&unnamed, &value); 191 192 if (ret != 0) { 193 UNRESOLVED(errno, "Failed to get sem value"); 194 } 195 196 if ((value != INIT_VAL) && (value != INIT_VAL + 1)) { 197 output("Got value %d, expected %d or %d only\n", 198 value, INIT_VAL, INIT_VAL + 1); 199 FAILED 200 ("sem_getvalue returned an invalid value for the unnamed semaphore"); 201 } 202 203 iterations++; 204 } 205 206 /* Join the threads */ 207 ret = pthread_join(child1, NULL); 208 209 if (ret != 0) { 210 UNRESOLVED(ret, "Failed to join a thread"); 211 } 212 213 ret = pthread_join(child2, NULL); 214 215 if (ret != 0) { 216 UNRESOLVED(ret, "Failed to join a thread"); 217 } 218 219 /* Destroy the semaphores */ 220 ret = sem_close(named); 221 222 if (ret != 0) { 223 UNRESOLVED(errno, "Failed to close the semaphore"); 224 } 225 226 ret = sem_destroy(&unnamed); 227 228 if (ret != 0) { 229 UNRESOLVED(errno, "Failed to destroy the semaphore"); 230 } 231 232 /* Passed */ 233 output("pthread_exit stress test PASSED -- %llu iterations\n", 234 iterations); 235 236 PASSED; 237 } 238