10dc076565f772bb1953209fb69ea150b494aaa40robbiew/* 20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2004, Bull S.A.. All rights reserved. 30dc076565f772bb1953209fb69ea150b494aaa40robbiew * Created by: Sebastien Decugis 40dc076565f772bb1953209fb69ea150b494aaa40robbiew 50dc076565f772bb1953209fb69ea150b494aaa40robbiew * This program is free software; you can redistribute it and/or modify it 60dc076565f772bb1953209fb69ea150b494aaa40robbiew * under the terms of version 2 of the GNU General Public License as 70dc076565f772bb1953209fb69ea150b494aaa40robbiew * published by the Free Software Foundation. 80dc076565f772bb1953209fb69ea150b494aaa40robbiew * 90dc076565f772bb1953209fb69ea150b494aaa40robbiew * This program is distributed in the hope that it would be useful, but 100dc076565f772bb1953209fb69ea150b494aaa40robbiew * WITHOUT ANY WARRANTY; without even the implied warranty of 110dc076565f772bb1953209fb69ea150b494aaa40robbiew * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * 130dc076565f772bb1953209fb69ea150b494aaa40robbiew * 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. 160dc076565f772bb1953209fb69ea150b494aaa40robbiew 170dc076565f772bb1953209fb69ea150b494aaa40robbiew * This sample test aims to check the following assertion: 180dc076565f772bb1953209fb69ea150b494aaa40robbiew * 192c28215423293e443469a07ae7011135d058b671Garrett Cooper * If the mutex is of type PTHREAD_MUTEX_RECURSIVE, 202c28215423293e443469a07ae7011135d058b671Garrett Cooper * and the calling thread already owns the mutex, 210dc076565f772bb1953209fb69ea150b494aaa40robbiew * the call is successful (the lock count is incremented). 220dc076565f772bb1953209fb69ea150b494aaa40robbiew 230dc076565f772bb1953209fb69ea150b494aaa40robbiew * The steps are: 240dc076565f772bb1953209fb69ea150b494aaa40robbiew * 250dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> trylock the mutex. It shall suceed. 260dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> trylock the mutex again. It shall suceed again 270dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> unlock once 280dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> create a new child (either thread or process) 290dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> the new child trylock the mutex. It shall fail. 300dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> Unlock. It shall succeed. 310dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> Unlock again. It shall fail. 320dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> undo everything. 330dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 342c28215423293e443469a07ae7011135d058b671Garrett Cooper 350dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _POSIX_C_SOURCE 200112L 372c28215423293e443469a07ae7011135d058b671Garrett Cooper 380dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We need the XSI extention for the mutex attributes 39354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao and the mkstemp() routine */ 400dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef WITHOUT_XOPEN 41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _XOPEN_SOURCE 600 420dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif 430dc076565f772bb1953209fb69ea150b494aaa40robbiew /********************************************************************************************/ 440dc076565f772bb1953209fb69ea150b494aaa40robbiew/****************************** standard includes *****************************************/ 450dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <pthread.h> 47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdarg.h> 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdio.h> 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdlib.h> 50354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <unistd.h> 510dc076565f772bb1953209fb69ea150b494aaa40robbiew 52354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <errno.h> 53354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <sys/wait.h> 54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <sys/mman.h> 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <string.h> 562c28215423293e443469a07ae7011135d058b671Garrett Cooper 570dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 580dc076565f772bb1953209fb69ea150b494aaa40robbiew/****************************** Test framework *****************************************/ 590dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "../testfrmw/testfrmw.h" 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "../testfrmw/testfrmw.c" 620dc076565f772bb1953209fb69ea150b494aaa40robbiew /* This header is responsible for defining the following macros: 632c28215423293e443469a07ae7011135d058b671Garrett Cooper * UNRESOLVED(ret, descr); 640dc076565f772bb1953209fb69ea150b494aaa40robbiew * where descr is a description of the error and ret is an int (error code for example) 650dc076565f772bb1953209fb69ea150b494aaa40robbiew * FAILED(descr); 660dc076565f772bb1953209fb69ea150b494aaa40robbiew * where descr is a short text saying why the test has failed. 670dc076565f772bb1953209fb69ea150b494aaa40robbiew * PASSED(); 680dc076565f772bb1953209fb69ea150b494aaa40robbiew * No parameter. 692c28215423293e443469a07ae7011135d058b671Garrett Cooper * 700dc076565f772bb1953209fb69ea150b494aaa40robbiew * Both three macros shall terminate the calling process. 710dc076565f772bb1953209fb69ea150b494aaa40robbiew * The testcase shall not terminate in any other maneer. 722c28215423293e443469a07ae7011135d058b671Garrett Cooper * 730dc076565f772bb1953209fb69ea150b494aaa40robbiew * The other file defines the functions 740dc076565f772bb1953209fb69ea150b494aaa40robbiew * void output_init() 750dc076565f772bb1953209fb69ea150b494aaa40robbiew * void output(char * string, ...) 762c28215423293e443469a07ae7011135d058b671Garrett Cooper * 770dc076565f772bb1953209fb69ea150b494aaa40robbiew * Those may be used to output information. 780dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 790dc076565f772bb1953209fb69ea150b494aaa40robbiew 800dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 810dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************** Configuration ******************************************/ 820dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 830dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef VERBOSE 840dc076565f772bb1953209fb69ea150b494aaa40robbiew#define VERBOSE 1 850dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif 860dc076565f772bb1953209fb69ea150b494aaa40robbiew 870dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 880dc076565f772bb1953209fb69ea150b494aaa40robbiew/*********************************** Test case *****************************************/ 890dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/ 900dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef WITHOUT_XOPEN 910dc076565f772bb1953209fb69ea150b494aaa40robbiew 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotypedef struct { 930dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_mutex_t mtx; 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int status; /* error code */ 950dc076565f772bb1953209fb69ea150b494aaa40robbiew} testdata_t; 960dc076565f772bb1953209fb69ea150b494aaa40robbiew 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct _scenar { 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int m_type; /* Mutex type to use */ 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int m_pshared; /* 0: mutex is process-private (default) ~ !0: mutex is process-shared, if supported */ 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int fork; /* 0: Test between threads. ~ !0: Test across processes, if supported (mmap) */ 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *descr; /* Case description */ 102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao} scenarii[] = { 103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao { 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_RECURSIVE, 0, 0, "Recursive mutex"} 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao , { 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_RECURSIVE, 1, 0, "Pshared Recursive mutex"} 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao , { 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_MUTEX_RECURSIVE, 1, 1, 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Pshared Recursive mutex across processes"} 1100dc076565f772bb1953209fb69ea150b494aaa40robbiew}; 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 1120dc076565f772bb1953209fb69ea150b494aaa40robbiew#define NSCENAR (sizeof(scenarii)/sizeof(scenarii[0])) 1130dc076565f772bb1953209fb69ea150b494aaa40robbiew 1140dc076565f772bb1953209fb69ea150b494aaa40robbiew/* The test function will only perform a trylock operation then return. */ 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *tf(void *arg) 1160dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao testdata_t *td = (testdata_t *) arg; 1182c28215423293e443469a07ae7011135d058b671Garrett Cooper 1190dc076565f772bb1953209fb69ea150b494aaa40robbiew td->status = pthread_mutex_trylock(&(td->mtx)); 1202c28215423293e443469a07ae7011135d058b671Garrett Cooper 121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (td->status == 0) { 1220dc076565f772bb1953209fb69ea150b494aaa40robbiew int ret; 1232c28215423293e443469a07ae7011135d058b671Garrett Cooper 1240dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_unlock(&(td->mtx)); 125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Failed to unlock a locked semaphore"); 127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1280dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1292c28215423293e443469a07ae7011135d058b671Garrett Cooper 1300dc076565f772bb1953209fb69ea150b494aaa40robbiew return NULL; 1310dc076565f772bb1953209fb69ea150b494aaa40robbiew} 1320dc076565f772bb1953209fb69ea150b494aaa40robbiew 1330dc076565f772bb1953209fb69ea150b494aaa40robbiew/* Main entry point. */ 1344ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 1350dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 1360dc076565f772bb1953209fb69ea150b494aaa40robbiew int ret; 1370dc076565f772bb1953209fb69ea150b494aaa40robbiew int sc; 1380dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_mutexattr_t ma; 1392c28215423293e443469a07ae7011135d058b671Garrett Cooper 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao testdata_t *td; 1410dc076565f772bb1953209fb69ea150b494aaa40robbiew testdata_t alternativ; 1422c28215423293e443469a07ae7011135d058b671Garrett Cooper 1430dc076565f772bb1953209fb69ea150b494aaa40robbiew int do_fork; 1442c28215423293e443469a07ae7011135d058b671Garrett Cooper 145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pid_t child_pr = 0, chkpid; 1460dc076565f772bb1953209fb69ea150b494aaa40robbiew int status; 1470dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_t child_th; 1482c28215423293e443469a07ae7011135d058b671Garrett Cooper 1490dc076565f772bb1953209fb69ea150b494aaa40robbiew long pshared, mf; 1502c28215423293e443469a07ae7011135d058b671Garrett Cooper 1510dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Initialize output */ 1520dc076565f772bb1953209fb69ea150b494aaa40robbiew output_init(); 1532c28215423293e443469a07ae7011135d058b671Garrett Cooper 1540dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Test system abilities */ 1550dc076565f772bb1953209fb69ea150b494aaa40robbiew pshared = sysconf(_SC_THREAD_PROCESS_SHARED); 156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao mf = sysconf(_SC_MAPPED_FILES); 1572c28215423293e443469a07ae7011135d058b671Garrett Cooper 158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 0 1590dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Test starting\n"); 1600dc076565f772bb1953209fb69ea150b494aaa40robbiew output("System abilities:\n"); 1610dc076565f772bb1953209fb69ea150b494aaa40robbiew output(" TSH : %li\n", pshared); 1620dc076565f772bb1953209fb69ea150b494aaa40robbiew output(" MF : %li\n", mf); 1630dc076565f772bb1953209fb69ea150b494aaa40robbiew if ((mf < 0) || (pshared < 0)) 1640dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Process-shared attributes won't be tested\n"); 165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 1660dc076565f772bb1953209fb69ea150b494aaa40robbiew 1670dc076565f772bb1953209fb69ea150b494aaa40robbiew/********** 1680dc076565f772bb1953209fb69ea150b494aaa40robbiew * Allocate space for the testdata structure 1690dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (mf < 0) { 1710dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Cannot mmap a file (or not interested in this), we use an alternative method */ 1720dc076565f772bb1953209fb69ea150b494aaa40robbiew td = &alternativ; 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pshared = -1; /* We won't do this testing anyway */ 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 0 1750dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Testdata allocated in the process memory.\n"); 176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 1780dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We will place the test data in a mmaped file */ 1790dc076565f772bb1953209fb69ea150b494aaa40robbiew char filename[] = "/tmp/mutex_trylock_2-1-XXXXXX"; 1800dc076565f772bb1953209fb69ea150b494aaa40robbiew size_t sz; 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao void *mmaped; 1820dc076565f772bb1953209fb69ea150b494aaa40robbiew int fd; 183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *tmp; 1842c28215423293e443469a07ae7011135d058b671Garrett Cooper 1850dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We now create the temp files */ 1860dc076565f772bb1953209fb69ea150b494aaa40robbiew fd = mkstemp(filename); 187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fd == -1) { 188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(errno, 189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Temporary file could not be created"); 190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1912c28215423293e443469a07ae7011135d058b671Garrett Cooper 1920dc076565f772bb1953209fb69ea150b494aaa40robbiew /* and make sure the file will be deleted when closed */ 1930dc076565f772bb1953209fb69ea150b494aaa40robbiew unlink(filename); 1942c28215423293e443469a07ae7011135d058b671Garrett Cooper 195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 1960dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Temp file created (%s).\n", filename); 197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 1982c28215423293e443469a07ae7011135d058b671Garrett Cooper 199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sz = (size_t) sysconf(_SC_PAGESIZE); 2002c28215423293e443469a07ae7011135d058b671Garrett Cooper 2010dc076565f772bb1953209fb69ea150b494aaa40robbiew tmp = calloc(1, sz); 202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (tmp == NULL) { 203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(errno, "Memory allocation failed"); 204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2052c28215423293e443469a07ae7011135d058b671Garrett Cooper 2060dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Write the data to the file. */ 207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(fd, tmp, sz) != (ssize_t) sz) { 208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(sz, "Writting to the file failed"); 209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2102c28215423293e443469a07ae7011135d058b671Garrett Cooper 2110dc076565f772bb1953209fb69ea150b494aaa40robbiew free(tmp); 2122c28215423293e443469a07ae7011135d058b671Garrett Cooper 2130dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Now we can map the file in memory */ 214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao mmaped = 215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (mmaped == MAP_FAILED) { 217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(errno, "mmap failed"); 218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2192c28215423293e443469a07ae7011135d058b671Garrett Cooper 2200dc076565f772bb1953209fb69ea150b494aaa40robbiew td = (testdata_t *) mmaped; 2212c28215423293e443469a07ae7011135d058b671Garrett Cooper 2220dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Our datatest structure is now in shared memory */ 223354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2240dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Testdata allocated in shared memory.\n"); 225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2260dc076565f772bb1953209fb69ea150b494aaa40robbiew } 2272c28215423293e443469a07ae7011135d058b671Garrett Cooper 2280dc076565f772bb1953209fb69ea150b494aaa40robbiew/********** 2290dc076565f772bb1953209fb69ea150b494aaa40robbiew * For each test scenario, initialize the attributes and other variables. 2300dc076565f772bb1953209fb69ea150b494aaa40robbiew * Do the whole thing for each time to test. 2310dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 232354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (sc = 0; sc < NSCENAR; sc++) { 233354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao output("[parent] Preparing attributes for: %s\n", 235354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao scenarii[sc].descr); 236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2370dc076565f772bb1953209fb69ea150b494aaa40robbiew /* set / reset everything */ 238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do_fork = 0; 2390dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutexattr_init(&ma); 240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, 242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "[parent] Unable to initialize the mutex attribute object"); 243354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2442c28215423293e443469a07ae7011135d058b671Garrett Cooper 2450dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Set the mutex type */ 2460dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutexattr_settype(&ma, scenarii[sc].m_type); 247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "[parent] Unable to set mutex type"); 249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2510dc076565f772bb1953209fb69ea150b494aaa40robbiew output("[parent] Mutex type : %i\n", scenarii[sc].m_type); 252354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2532c28215423293e443469a07ae7011135d058b671Garrett Cooper 2540dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Set the pshared attributes, if supported */ 255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((pshared > 0) && (scenarii[sc].m_pshared != 0)) { 256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ret = 257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthread_mutexattr_setpshared(&ma, 258354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PTHREAD_PROCESS_SHARED); 259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, 261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "[parent] Unable to set the mutex process-shared"); 262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2640dc076565f772bb1953209fb69ea150b494aaa40robbiew output("[parent] Mutex is process-shared\n"); 265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2660dc076565f772bb1953209fb69ea150b494aaa40robbiew } 267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2680dc076565f772bb1953209fb69ea150b494aaa40robbiew else { 2690dc076565f772bb1953209fb69ea150b494aaa40robbiew output("[parent] Mutex is process-private\n"); 2700dc076565f772bb1953209fb69ea150b494aaa40robbiew } 271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2722c28215423293e443469a07ae7011135d058b671Garrett Cooper 2730dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Tell whether the test will be across processes */ 274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((pshared > 0) && (scenarii[sc].fork != 0)) { 2750dc076565f772bb1953209fb69ea150b494aaa40robbiew do_fork = 1; 276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2770dc076565f772bb1953209fb69ea150b494aaa40robbiew output("[parent] Child will be a new process\n"); 278354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2790dc076565f772bb1953209fb69ea150b494aaa40robbiew } 280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1 2810dc076565f772bb1953209fb69ea150b494aaa40robbiew else { 2820dc076565f772bb1953209fb69ea150b494aaa40robbiew output("[parent] Child will be a new thread\n"); 2830dc076565f772bb1953209fb69ea150b494aaa40robbiew } 284354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 2852c28215423293e443469a07ae7011135d058b671Garrett Cooper 2860dc076565f772bb1953209fb69ea150b494aaa40robbiew/********** 2872c28215423293e443469a07ae7011135d058b671Garrett Cooper * Initialize the testdata_t structure with the previously defined attributes 2880dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 2890dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Initialize the mutex */ 2900dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_init(&(td->mtx), &ma); 291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "[parent] Mutex init failed"); 293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 2942c28215423293e443469a07ae7011135d058b671Garrett Cooper 2950dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Initialize the other datas from the test structure */ 296354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao td->status = 0; 2972c28215423293e443469a07ae7011135d058b671Garrett Cooper 2980dc076565f772bb1953209fb69ea150b494aaa40robbiew/********** 2992c28215423293e443469a07ae7011135d058b671Garrett Cooper * Proceed to the actual testing 3000dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 3010dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Trylock the mutex twice before creating children */ 3020dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_trylock(&(td->mtx)); 303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "[parent] Unable to trylock the mutex"); 305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 3060dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_trylock(&(td->mtx)); 3070dc076565f772bb1953209fb69ea150b494aaa40robbiew 308354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (scenarii[sc].m_type == PTHREAD_MUTEX_RECURSIVE) { 309354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 310354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED 311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Failed to pthread_mutex_trylock() twice a recursive mutex"); 312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 3132c28215423293e443469a07ae7011135d058b671Garrett Cooper 3140dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Unlock once so the count is "1" */ 3150dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_unlock(&(td->mtx)); 316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Failed to unlock the mutex"); 318354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 319354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (ret == 0) { 320354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(-1, 321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Main was able to pthread_mutex_trylock() twice without error"); 3220dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3232c28215423293e443469a07ae7011135d058b671Garrett Cooper 3240dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Create the children */ 325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (do_fork != 0) { 3260dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We are testing across processes */ 3270dc076565f772bb1953209fb69ea150b494aaa40robbiew child_pr = fork(); 328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (child_pr == -1) { 329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(errno, "[parent] Fork failed"); 330354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 331354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 332354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (child_pr == 0) { 333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 3 334354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao output 335354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("[child] Child process is starting...\n"); 336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 338354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (tf((void *)td) != NULL) { 339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(-1, 340354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "[child] Got an unexpected return value from test function"); 341354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 3420dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We cannot use the PASSED macro here since it would terminate the output */ 343354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(0); 3440dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3450dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3460dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Only the parent process goes further */ 347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { /* do_fork == 0 */ 348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 3490dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We are testing across two threads */ 3500dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_create(&child_th, NULL, tf, td); 351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 352354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, 353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "[parent] Unable to create the child thread."); 354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 3550dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3562c28215423293e443469a07ae7011135d058b671Garrett Cooper 3570dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Wait for the child to terminate */ 358354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (do_fork != 0) { 3590dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We were testing across processes */ 3600dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = 0; 3610dc076565f772bb1953209fb69ea150b494aaa40robbiew chkpid = waitpid(child_pr, &status, 0); 362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (chkpid != child_pr) { 363354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao output("Expected pid: %i. Got %i\n", 364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (int)child_pr, (int)chkpid); 3652c28215423293e443469a07ae7011135d058b671Garrett Cooper UNRESOLVED(errno, "Waitpid failed"); 3660dc076565f772bb1953209fb69ea150b494aaa40robbiew } 367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (WIFSIGNALED(status)) { 368354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao output("Child process killed with signal %d\n", 369354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao WTERMSIG(status)); 370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(-1, "Child process was killed"); 3710dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3722c28215423293e443469a07ae7011135d058b671Garrett Cooper 373354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (WIFEXITED(status)) { 3740dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = WEXITSTATUS(status); 375354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 376354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(-1, 377354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Child process was neither killed nor exited"); 3780dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3792c28215423293e443469a07ae7011135d058b671Garrett Cooper 380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 381354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(ret); /* Output has already been closed in child */ 3820dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3832c28215423293e443469a07ae7011135d058b671Garrett Cooper 384354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { /* child was a thread */ 385354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 3860dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_join(child_th, NULL); 387354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 388354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, 389354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "[parent] Unable to join the thread"); 390354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 3910dc076565f772bb1953209fb69ea150b494aaa40robbiew } 3922c28215423293e443469a07ae7011135d058b671Garrett Cooper 3930dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Check the child status */ 394354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (td->status != EBUSY) { 395354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao output("Unexpected return value: %d (%s)\n", td->status, 396354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao strerror(td->status)); 397354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED 398354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("pthread_mutex_trylock() did not return EBUSY in the child"); 3990dc076565f772bb1953209fb69ea150b494aaa40robbiew } 4002c28215423293e443469a07ae7011135d058b671Garrett Cooper 4010dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Unlock the mutex */ 402354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ret = pthread_mutex_unlock(&(td->mtx)); 403354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 404354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED 405354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Failed to unlock the mutex -- count is broken?"); 406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 4072c28215423293e443469a07ae7011135d058b671Garrett Cooper 408354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ret = pthread_mutex_unlock(&(td->mtx)); 409354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret == 0) { 410354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FAILED 411354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Was able to unlock once more the mutex -- count is broken?"); 412354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 4132c28215423293e443469a07ae7011135d058b671Garrett Cooper 4140dc076565f772bb1953209fb69ea150b494aaa40robbiew/********** 4152c28215423293e443469a07ae7011135d058b671Garrett Cooper * Destroy the data 4160dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 4170dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutex_destroy(&(td->mtx)); 418354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 419354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, "Failed to destroy the mutex"); 420354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 4212c28215423293e443469a07ae7011135d058b671Garrett Cooper 4220dc076565f772bb1953209fb69ea150b494aaa40robbiew ret = pthread_mutexattr_destroy(&ma); 423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ret != 0) { 424354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao UNRESOLVED(ret, 425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Failed to destroy the mutex attribute object"); 426354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 4272c28215423293e443469a07ae7011135d058b671Garrett Cooper 428354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } /* Proceed to the next scenario */ 4292c28215423293e443469a07ae7011135d058b671Garrett Cooper 430354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 0 4310dc076565f772bb1953209fb69ea150b494aaa40robbiew output("Test passed\n"); 432354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 4330dc076565f772bb1953209fb69ea150b494aaa40robbiew 4340dc076565f772bb1953209fb69ea150b494aaa40robbiew PASSED; 4350dc076565f772bb1953209fb69ea150b494aaa40robbiew} 4360dc076565f772bb1953209fb69ea150b494aaa40robbiew 4370dc076565f772bb1953209fb69ea150b494aaa40robbiew#else /* WITHOUT_XOPEN */ 4384ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 4390dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 4400dc076565f772bb1953209fb69ea150b494aaa40robbiew output_init(); 4410dc076565f772bb1953209fb69ea150b494aaa40robbiew UNTESTED("This test requires XSI features"); 4420dc076565f772bb1953209fb69ea150b494aaa40robbiew} 443ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman#endif 444