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 * This sample test aims to check the following assertion: 18 * 19 * It is safe to destroy an initialized unlocked mutex. 20 21 * The steps are: 22 * -> Initialize a mutex with a given attribute. 23 * -> Lock the mutex 24 * -> unlock the mutex 25 * -> Destroy the mutex -- this shall return 0. 26 27 */ 28 29 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 30#define _POSIX_C_SOURCE 200112L 31 32 /* We need the XSI extention for the mutex attributes */ 33#ifndef WITHOUT_XOPEN 34#define _XOPEN_SOURCE 600 35#endif 36 /********************************************************************************************/ 37/****************************** standard includes *****************************************/ 38/********************************************************************************************/ 39#include <pthread.h> 40#include <stdarg.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <unistd.h> 44 45/********************************************************************************************/ 46/****************************** Test framework *****************************************/ 47/********************************************************************************************/ 48#include "../testfrmw/testfrmw.h" 49#include "../testfrmw/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 VERBOSE 72#define VERBOSE 1 73#endif 74 75/********************************************************************************************/ 76/*********************************** Test case *****************************************/ 77/********************************************************************************************/ 78#ifndef WITHOUT_XOPEN 79 80struct _scenar { 81 int m_type; /* Mutex type to use */ 82 int m_pshared; /* 0: mutex is process-private (default) ~ !0: mutex is process-shared, if supported */ 83 char *descr; /* Case description */ 84} scenarii[] = { 85 { 86 PTHREAD_MUTEX_DEFAULT, 0, "Default mutex"} 87 , { 88 PTHREAD_MUTEX_NORMAL, 0, "Normal mutex"} 89 , { 90 PTHREAD_MUTEX_ERRORCHECK, 0, "Errorcheck mutex"} 91 , { 92 PTHREAD_MUTEX_RECURSIVE, 0, "Recursive mutex"} 93 94 , { 95 PTHREAD_MUTEX_DEFAULT, 1, "Pshared mutex"} 96 , { 97 PTHREAD_MUTEX_NORMAL, 1, "Pshared Normal mutex"} 98 , { 99 PTHREAD_MUTEX_ERRORCHECK, 1, "Pshared Errorcheck mutex"} 100 , { 101 PTHREAD_MUTEX_RECURSIVE, 1, "Pshared Recursive mutex"} 102}; 103 104#define NSCENAR (sizeof(scenarii)/sizeof(scenarii[0])) 105 106/* Main function */ 107int main(void) 108{ 109 int ret; 110 int i; 111 pthread_mutex_t mtx; 112 pthread_mutexattr_t ma[NSCENAR + 1]; 113 pthread_mutexattr_t *pma[NSCENAR + 2]; 114 long pshared; 115 116 /* Initialize output routine */ 117 output_init(); 118 119 /* System abilities */ 120 pshared = sysconf(_SC_THREAD_PROCESS_SHARED); 121 122 /* Initialize the mutex attributes objects */ 123 for (i = 0; i < NSCENAR; i++) { 124 ret = pthread_mutexattr_init(&ma[i]); 125 if (ret != 0) { 126 UNRESOLVED(ret, 127 "[parent] Unable to initialize the mutex attribute object"); 128 } 129 130 /* Set the mutex type */ 131 ret = pthread_mutexattr_settype(&ma[i], scenarii[i].m_type); 132 if (ret != 0) { 133 UNRESOLVED(ret, "[parent] Unable to set mutex type"); 134 } 135 136 /* Set the pshared attributes, if supported */ 137 if ((pshared > 0) && (scenarii[i].m_pshared != 0)) { 138 ret = 139 pthread_mutexattr_setpshared(&ma[i], 140 PTHREAD_PROCESS_SHARED); 141 if (ret != 0) { 142 UNRESOLVED(ret, 143 "[parent] Unable to set the mutex process-shared"); 144 } 145 } 146 } 147 /* Default mutexattr object */ 148 ret = pthread_mutexattr_init(&ma[i]); 149 if (ret != 0) { 150 UNRESOLVED(ret, 151 "[parent] Unable to initialize the mutex attribute object"); 152 } 153 154 /* Initialize the pointer array */ 155 for (i = 0; i < NSCENAR + 1; i++) 156 pma[i] = &ma[i]; 157 158 /* NULL pointer */ 159 pma[i] = NULL; 160 161 /* Ok, we can now proceed to the test */ 162#if VERBOSE > 0 163 output("Attributes are ready, proceed to the test\n"); 164#endif 165 166 for (i = 0; i < NSCENAR + 2; i++) { 167#if VERBOSE > 1 168 char *nul = "NULL"; 169 char *def = "Default"; 170 char *stri; 171 if (i < NSCENAR) 172 stri = scenarii[i].descr; 173 if (i == NSCENAR) 174 stri = def; 175 if (i == NSCENAR + 1) 176 stri = nul; 177 178 output("Init with: %s\n", stri); 179#endif 180 181 ret = pthread_mutex_init(&mtx, pma[i]); 182 if (ret != 0) { 183 UNRESOLVED(ret, "Failed to init the mutex"); 184 } 185 186 ret = pthread_mutex_lock(&mtx); 187 if (ret != 0) { 188 UNRESOLVED(ret, "Failed to lock the mutex"); 189 } 190 191 ret = pthread_mutex_unlock(&mtx); 192 if (ret != 0) { 193 UNRESOLVED(ret, "Failed to unlcok the mutex"); 194 } 195 196 ret = pthread_mutex_destroy(&mtx); 197 if (ret != 0) { 198 FAILED 199 ("Failed to destroy an initialized unlocked mutex"); 200 } 201 202 } 203 204#if VERBOSE > 0 205 output("Test passed; destroying the test data\n"); 206#endif 207 208 for (i = 0; i < NSCENAR + 1; i++) { 209 ret = pthread_mutexattr_destroy(&ma[i]); 210 if (ret != 0) { 211 UNRESOLVED(ret, 212 "Failed to destroy a mutex attribute object"); 213 } 214 } 215 216 PASSED; 217} 218 219#else /* WITHOUT_XOPEN */ 220int main(void) 221{ 222 output_init(); 223 UNTESTED("This test requires XSI features"); 224} 225#endif 226