12c28215423293e443469a07ae7011135d058b671Garrett Cooper/* 22c28215423293e443469a07ae7011135d058b671Garrett Cooper * Copyright (c) 2004, Bull S.A.. All rights reserved. 32c28215423293e443469a07ae7011135d058b671Garrett Cooper * Created by: Sebastien Decugis 42c28215423293e443469a07ae7011135d058b671Garrett Cooper 52c28215423293e443469a07ae7011135d058b671Garrett Cooper * This program is free software; you can redistribute it and/or modify it 62c28215423293e443469a07ae7011135d058b671Garrett Cooper * under the terms of version 2 of the GNU General Public License as 72c28215423293e443469a07ae7011135d058b671Garrett Cooper * published by the Free Software Foundation. 82c28215423293e443469a07ae7011135d058b671Garrett Cooper * 92c28215423293e443469a07ae7011135d058b671Garrett Cooper * This program is distributed in the hope that it would be useful, but 102c28215423293e443469a07ae7011135d058b671Garrett Cooper * WITHOUT ANY WARRANTY; without even the implied warranty of 112c28215423293e443469a07ae7011135d058b671Garrett Cooper * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 122c28215423293e443469a07ae7011135d058b671Garrett Cooper * 132c28215423293e443469a07ae7011135d058b671Garrett Cooper * You should have received a copy of the GNU General Public License along 14fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * with this program; if not, write the Free Software Foundation, Inc., 15fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 162c28215423293e443469a07ae7011135d058b671Garrett Cooper * 172c28215423293e443469a07ae7011135d058b671Garrett Cooper 182c28215423293e443469a07ae7011135d058b671Garrett Cooper * This file is a stress test for the pthread_mutex_init function. 192c28215423293e443469a07ae7011135d058b671Garrett Cooper 202c28215423293e443469a07ae7011135d058b671Garrett Cooper * The steps are: 212c28215423293e443469a07ae7011135d058b671Garrett Cooper * -> Create some threads 222c28215423293e443469a07ae7011135d058b671Garrett Cooper * -> each thread loops on initializing and destroying a mutex 232c28215423293e443469a07ae7011135d058b671Garrett Cooper * -> the whole process stop when receiving signal SIGUSR1 242c28215423293e443469a07ae7011135d058b671Garrett Cooper */ 252c28215423293e443469a07ae7011135d058b671Garrett Cooper 262c28215423293e443469a07ae7011135d058b671Garrett Cooper /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 27354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _POSIX_C_SOURCE 200112L 282c28215423293e443469a07ae7011135d058b671Garrett Cooper 292c28215423293e443469a07ae7011135d058b671Garrett Cooper /* We enable the following line to have mutex attributes defined */ 302c28215423293e443469a07ae7011135d058b671Garrett Cooper#ifndef WITHOUT_XOPEN 31354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _XOPEN_SOURCE 600 322c28215423293e443469a07ae7011135d058b671Garrett Cooper#endif 332c28215423293e443469a07ae7011135d058b671Garrett Cooper 342c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 352c28215423293e443469a07ae7011135d058b671Garrett Cooper/****************************** standard includes *****************************************/ 362c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 37354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <pthread.h> 38354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <errno.h> 39354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <signal.h> 40354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <unistd.h> 41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdio.h> 42354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdlib.h> 43354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdarg.h> 442c28215423293e443469a07ae7011135d058b671Garrett Cooper 452c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 462c28215423293e443469a07ae7011135d058b671Garrett Cooper/****************************** Test framework *****************************************/ 472c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "testfrmw.h" 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "testfrmw.c" 502c28215423293e443469a07ae7011135d058b671Garrett Cooper /* This header is responsible for defining the following macros: 512c28215423293e443469a07ae7011135d058b671Garrett Cooper * UNRESOLVED(ret, descr); 522c28215423293e443469a07ae7011135d058b671Garrett Cooper * where descr is a description of the error and ret is an int (error code for example) 532c28215423293e443469a07ae7011135d058b671Garrett Cooper * FAILED(descr); 542c28215423293e443469a07ae7011135d058b671Garrett Cooper * where descr is a short text saying why the test has failed. 552c28215423293e443469a07ae7011135d058b671Garrett Cooper * PASSED(); 562c28215423293e443469a07ae7011135d058b671Garrett Cooper * No parameter. 572c28215423293e443469a07ae7011135d058b671Garrett Cooper * 582c28215423293e443469a07ae7011135d058b671Garrett Cooper * Both three macros shall terminate the calling process. 592c28215423293e443469a07ae7011135d058b671Garrett Cooper * The testcase shall not terminate in any other maneer. 602c28215423293e443469a07ae7011135d058b671Garrett Cooper * 612c28215423293e443469a07ae7011135d058b671Garrett Cooper * The other file defines the functions 622c28215423293e443469a07ae7011135d058b671Garrett Cooper * void output_init() 632c28215423293e443469a07ae7011135d058b671Garrett Cooper * void output(char * string, ...) 642c28215423293e443469a07ae7011135d058b671Garrett Cooper * 652c28215423293e443469a07ae7011135d058b671Garrett Cooper * Those may be used to output information. 662c28215423293e443469a07ae7011135d058b671Garrett Cooper */ 672c28215423293e443469a07ae7011135d058b671Garrett Cooper 682c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 692c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************** Configuration ******************************************/ 702c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 712c28215423293e443469a07ae7011135d058b671Garrett Cooper#ifndef SCALABILITY_FACTOR 722c28215423293e443469a07ae7011135d058b671Garrett Cooper#define SCALABILITY_FACTOR 1 732c28215423293e443469a07ae7011135d058b671Garrett Cooper#endif 742c28215423293e443469a07ae7011135d058b671Garrett Cooper#ifndef VERBOSE 752c28215423293e443469a07ae7011135d058b671Garrett Cooper#define VERBOSE 2 762c28215423293e443469a07ae7011135d058b671Garrett Cooper#endif 772c28215423293e443469a07ae7011135d058b671Garrett Cooper#define N 20 782c28215423293e443469a07ae7011135d058b671Garrett Cooper 792c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 802c28215423293e443469a07ae7011135d058b671Garrett Cooper/*********************************** Test case *****************************************/ 812c28215423293e443469a07ae7011135d058b671Garrett Cooper/********************************************************************************************/ 82354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaochar do_it = 1; 832c28215423293e443469a07ae7011135d058b671Garrett Cooper#ifndef WITHOUT_XOPEN 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint types[] = { PTHREAD_MUTEX_NORMAL, 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_ERRORCHECK, 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_RECURSIVE, 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_DEFAULT 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}; 892c28215423293e443469a07ae7011135d058b671Garrett Cooper#endif 902c28215423293e443469a07ae7011135d058b671Garrett Cooper 912c28215423293e443469a07ae7011135d058b671Garrett Cooper/******** Threads function *********/ 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *threaded(void *arg) 932c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int me = (int)arg; 952c28215423293e443469a07ae7011135d058b671Garrett Cooper pthread_mutex_t mtx; 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthread_mutex_t *pmtx; 972c28215423293e443469a07ae7011135d058b671Garrett Cooper pthread_mutexattr_t ma; 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthread_mutexattr_t *pma; 992c28215423293e443469a07ae7011135d058b671Garrett Cooper int ret; 1002c28215423293e443469a07ae7011135d058b671Garrett Cooper#ifndef WITHOUT_XOPEN 1012c28215423293e443469a07ae7011135d058b671Garrett Cooper int sz = 2 + (sizeof(types) / sizeof(int)); 1022c28215423293e443469a07ae7011135d058b671Garrett Cooper#else 1032c28215423293e443469a07ae7011135d058b671Garrett Cooper int sz = 2; 1042c28215423293e443469a07ae7011135d058b671Garrett Cooper#endif 1052c28215423293e443469a07ae7011135d058b671Garrett Cooper /* We will use mutex from the stack or from malloc'ed memory */ 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char loc = ((me % 5) % 2); 1072c28215423293e443469a07ae7011135d058b671Garrett Cooper 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (loc) { 1092c28215423293e443469a07ae7011135d058b671Garrett Cooper pmtx = &mtx; 110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 111d218f348c12b42a78fa0306d9a033bfa4f67238bCyril Hrubis pmtx = malloc(sizeof(pthread_mutex_t)); 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pmtx == NULL) { 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(errno, "Memory allocation for mutex failed"); 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1152c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1162c28215423293e443469a07ae7011135d058b671Garrett Cooper 1172c28215423293e443469a07ae7011135d058b671Garrett Cooper me %= sz; 1182c28215423293e443469a07ae7011135d058b671Garrett Cooper 119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao switch (me) { 120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 0: /* We will initialize the mutex with NULL pointer */ 121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pma = NULL; 122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 1232c28215423293e443469a07ae7011135d058b671Garrett Cooper 124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao default: /* We will initialize the mutex with an attribute object */ 125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((ret = pthread_mutexattr_init(&ma))) { 126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Mutex attribute init failed"); 127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pma = &ma; 1292c28215423293e443469a07ae7011135d058b671Garrett Cooper 130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (me == 1) 131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 1322c28215423293e443469a07ae7011135d058b671Garrett Cooper 133354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((ret = pthread_mutexattr_settype(&ma, types[me - 2]))) { 134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Mutex attribute settype failed"); 135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1362c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1372c28215423293e443469a07ae7011135d058b671Garrett Cooper 138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao while (do_it) { 1392c28215423293e443469a07ae7011135d058b671Garrett Cooper ret = pthread_mutex_init(pmtx, pma); 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Mutex init failed"); 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1432c28215423293e443469a07ae7011135d058b671Garrett Cooper /* We use the mutex to check everything is OK */ 1442c28215423293e443469a07ae7011135d058b671Garrett Cooper ret = pthread_mutex_lock(pmtx); 145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Mutex lock failed"); 147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1482c28215423293e443469a07ae7011135d058b671Garrett Cooper ret = pthread_mutex_unlock(pmtx); 149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Mutex unlock failed"); 151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1522c28215423293e443469a07ae7011135d058b671Garrett Cooper ret = pthread_mutex_destroy(pmtx); 153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Mutex destroy failed"); 155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1562c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1572c28215423293e443469a07ae7011135d058b671Garrett Cooper 158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!loc) /* mutex was malloc'ed */ 1592c28215423293e443469a07ae7011135d058b671Garrett Cooper free(pmtx); 1602c28215423293e443469a07ae7011135d058b671Garrett Cooper 1612c28215423293e443469a07ae7011135d058b671Garrett Cooper if (me) 162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((ret = pthread_mutexattr_destroy(pma))) { 163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Mutex attribute destroy failed at the end"); 164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1652c28215423293e443469a07ae7011135d058b671Garrett Cooper 1662c28215423293e443469a07ae7011135d058b671Garrett Cooper return NULL; 1672c28215423293e443469a07ae7011135d058b671Garrett Cooper} 1682c28215423293e443469a07ae7011135d058b671Garrett Cooper 1692c28215423293e443469a07ae7011135d058b671Garrett Cooper/******** Signal handler ************/ 1702c28215423293e443469a07ae7011135d058b671Garrett Coopervoid sighdl(int sig) 1712c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do { 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do_it = 0; 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1752c28215423293e443469a07ae7011135d058b671Garrett Cooper while (do_it); 1762c28215423293e443469a07ae7011135d058b671Garrett Cooper} 1772c28215423293e443469a07ae7011135d058b671Garrett Cooper 1782c28215423293e443469a07ae7011135d058b671Garrett Cooper/******** Parent thread *************/ 179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char *argv[]) 1802c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 1812c28215423293e443469a07ae7011135d058b671Garrett Cooper struct sigaction sa; 1822c28215423293e443469a07ae7011135d058b671Garrett Cooper pthread_t threads[N * SCALABILITY_FACTOR]; 1832c28215423293e443469a07ae7011135d058b671Garrett Cooper int i; 1842c28215423293e443469a07ae7011135d058b671Garrett Cooper int ret; 1852c28215423293e443469a07ae7011135d058b671Garrett Cooper 1862c28215423293e443469a07ae7011135d058b671Garrett Cooper output_init(); 1872c28215423293e443469a07ae7011135d058b671Garrett Cooper 188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sigemptyset(&sa.sa_mask); 1892c28215423293e443469a07ae7011135d058b671Garrett Cooper sa.sa_flags = 0; 1902c28215423293e443469a07ae7011135d058b671Garrett Cooper sa.sa_handler = sighdl; 191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((ret = sigaction(SIGUSR1, &sa, NULL))) { 192354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Unable to register signal handler"); 193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1942c28215423293e443469a07ae7011135d058b671Garrett Cooper 195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; (i < (N * SCALABILITY_FACTOR) && (ret == 0)); i++) { 196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ret = pthread_create(&threads[i], NULL, threaded, (void *)i); 1972c28215423293e443469a07ae7011135d058b671Garrett Cooper } 198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { /* A thread creation failed */ 199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Stop the started threads */ 200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do { 201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do_it = 0; 202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2032c28215423293e443469a07ae7011135d058b671Garrett Cooper while (do_it); 204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (; i > 0; i--) 205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthread_join(threads[i - 1], NULL); 2062c28215423293e443469a07ae7011135d058b671Garrett Cooper 2072c28215423293e443469a07ae7011135d058b671Garrett Cooper UNRESOLVED(ret, "Unable to create enough threads"); 2082c28215423293e443469a07ae7011135d058b671Garrett Cooper } 2092c28215423293e443469a07ae7011135d058b671Garrett Cooper 2102c28215423293e443469a07ae7011135d058b671Garrett Cooper /* Every threads were created; we now just wait */ 211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < (N * SCALABILITY_FACTOR); i++) { 212354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((ret = pthread_join(threads[i], NULL))) { 213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED("Unable to join a thread"); 214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2152c28215423293e443469a07ae7011135d058b671Garrett Cooper } 216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 0 2172c28215423293e443469a07ae7011135d058b671Garrett Cooper output("pthread_mutex_init stress test passed\n"); 218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2192c28215423293e443469a07ae7011135d058b671Garrett Cooper 2202c28215423293e443469a07ae7011135d058b671Garrett Cooper /* Everything went OK */ 2212c28215423293e443469a07ae7011135d058b671Garrett Cooper PASSED; 222ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 223