1 /* 2 * Copyright (c) 2004, 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 18 * This file is a stress test for the pthread_mutex_init function. 19 20 * The steps are: 21 * -> Create some threads 22 * -> each thread loops on initializing and destroying a mutex 23 * -> the whole process stop when receiving signal SIGUSR1 24 */ 25 26 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 27 #define _POSIX_C_SOURCE 200112L 28 29 /* We enable the following line to have mutex attributes defined */ 30 #ifndef WITHOUT_XOPEN 31 #define _XOPEN_SOURCE 600 32 #endif 33 34 /********************************************************************************************/ 35 /****************************** standard includes *****************************************/ 36 /********************************************************************************************/ 37 #include <pthread.h> 38 #include <errno.h> 39 #include <signal.h> 40 #include <unistd.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <stdarg.h> 44 45 /********************************************************************************************/ 46 /****************************** Test framework *****************************************/ 47 /********************************************************************************************/ 48 #include "testfrmw.h" 49 #include "testfrmw.c" 50 /* This header is responsible for defining the following macros: 51 * UNRESOLVED(ret, descr); 52 * where descr is a description of the error and ret is an int (error code for example) 53 * FAILED(descr); 54 * where descr is a short text saying why the test has failed. 55 * PASSED(); 56 * No parameter. 57 * 58 * Both three macros shall terminate the calling process. 59 * The testcase shall not terminate in any other maneer. 60 * 61 * The other file defines the functions 62 * void output_init() 63 * void output(char * string, ...) 64 * 65 * Those may be used to output information. 66 */ 67 68 /********************************************************************************************/ 69 /********************************** Configuration ******************************************/ 70 /********************************************************************************************/ 71 #ifndef SCALABILITY_FACTOR 72 #define SCALABILITY_FACTOR 1 73 #endif 74 #ifndef VERBOSE 75 #define VERBOSE 2 76 #endif 77 #define N 20 78 79 /********************************************************************************************/ 80 /*********************************** Test case *****************************************/ 81 /********************************************************************************************/ 82 char do_it = 1; 83 #ifndef WITHOUT_XOPEN 84 int types[] = { PTHREAD_MUTEX_NORMAL, 85 PTHREAD_MUTEX_ERRORCHECK, 86 PTHREAD_MUTEX_RECURSIVE, 87 PTHREAD_MUTEX_DEFAULT 88 }; 89 #endif 90 91 /******** Threads function *********/ 92 void *threaded(void *arg) 93 { 94 int me = (int)arg; 95 pthread_mutex_t mtx; 96 pthread_mutex_t *pmtx; 97 pthread_mutexattr_t ma; 98 pthread_mutexattr_t *pma; 99 int ret; 100 #ifndef WITHOUT_XOPEN 101 int sz = 2 + (sizeof(types) / sizeof(int)); 102 #else 103 int sz = 2; 104 #endif 105 /* We will use mutex from the stack or from malloc'ed memory */ 106 char loc = ((me % 5) % 2); 107 108 if (loc) { 109 pmtx = &mtx; 110 } else { 111 pmtx = malloc(sizeof(pthread_mutex_t)); 112 if (pmtx == NULL) { 113 UNRESOLVED(errno, "Memory allocation for mutex failed"); 114 } 115 } 116 117 me %= sz; 118 119 switch (me) { 120 case 0: /* We will initialize the mutex with NULL pointer */ 121 pma = NULL; 122 break; 123 124 default: /* We will initialize the mutex with an attribute object */ 125 if ((ret = pthread_mutexattr_init(&ma))) { 126 UNRESOLVED(ret, "Mutex attribute init failed"); 127 } 128 pma = &ma; 129 130 if (me == 1) 131 break; 132 133 if ((ret = pthread_mutexattr_settype(&ma, types[me - 2]))) { 134 UNRESOLVED(ret, "Mutex attribute settype failed"); 135 } 136 } 137 138 while (do_it) { 139 ret = pthread_mutex_init(pmtx, pma); 140 if (ret != 0) { 141 FAILED("Mutex init failed"); 142 } 143 /* We use the mutex to check everything is OK */ 144 ret = pthread_mutex_lock(pmtx); 145 if (ret != 0) { 146 FAILED("Mutex lock failed"); 147 } 148 ret = pthread_mutex_unlock(pmtx); 149 if (ret != 0) { 150 FAILED("Mutex unlock failed"); 151 } 152 ret = pthread_mutex_destroy(pmtx); 153 if (ret != 0) { 154 FAILED("Mutex destroy failed"); 155 } 156 } 157 158 if (!loc) /* mutex was malloc'ed */ 159 free(pmtx); 160 161 if (me) 162 if ((ret = pthread_mutexattr_destroy(pma))) { 163 FAILED("Mutex attribute destroy failed at the end"); 164 } 165 166 return NULL; 167 } 168 169 /******** Signal handler ************/ 170 void sighdl(int sig) 171 { 172 do { 173 do_it = 0; 174 } 175 while (do_it); 176 } 177 178 /******** Parent thread *************/ 179 int main(int argc, char *argv[]) 180 { 181 struct sigaction sa; 182 pthread_t threads[N * SCALABILITY_FACTOR]; 183 int i; 184 int ret; 185 186 output_init(); 187 188 sigemptyset(&sa.sa_mask); 189 sa.sa_flags = 0; 190 sa.sa_handler = sighdl; 191 if ((ret = sigaction(SIGUSR1, &sa, NULL))) { 192 UNRESOLVED(ret, "Unable to register signal handler"); 193 } 194 195 for (i = 0; (i < (N * SCALABILITY_FACTOR) && (ret == 0)); i++) { 196 ret = pthread_create(&threads[i], NULL, threaded, (void *)i); 197 } 198 if (ret != 0) { /* A thread creation failed */ 199 /* Stop the started threads */ 200 do { 201 do_it = 0; 202 } 203 while (do_it); 204 for (; i > 0; i--) 205 pthread_join(threads[i - 1], NULL); 206 207 UNRESOLVED(ret, "Unable to create enough threads"); 208 } 209 210 /* Every threads were created; we now just wait */ 211 for (i = 0; i < (N * SCALABILITY_FACTOR); i++) { 212 if ((ret = pthread_join(threads[i], NULL))) { 213 FAILED("Unable to join a thread"); 214 } 215 } 216 #if VERBOSE > 0 217 output("pthread_mutex_init stress test passed\n"); 218 #endif 219 220 /* Everything went OK */ 221 PASSED; 222 } 223