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., 59 15* Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 17 18* This sample test aims to check the following assertion: 19* 20* Subsequent calls with the same once_control do not call init routine. 21 22* The steps are: 23* -> Create several threads 24* -> each call pthread_once 25* -> check the init_routine executed once 26 27* The test fails if the init_routine has not been called or has 28* been called several times. 29 30*/ 31 32 33/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 34#define _POSIX_C_SOURCE 200112L 35 36/********************************************************************************************/ 37/****************************** standard includes *****************************************/ 38/********************************************************************************************/ 39#include <pthread.h> 40#include <stdarg.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <unistd.h> 45 46/********************************************************************************************/ 47/****************************** Test framework *****************************************/ 48/********************************************************************************************/ 49#include "testfrmw.h" 50 #include "testfrmw.c" 51/* This header is responsible for defining the following macros: 52 * UNRESOLVED(ret, descr); 53 * where descr is a description of the error and ret is an int (error code for example) 54 * FAILED(descr); 55 * where descr is a short text saying why the test has failed. 56 * PASSED(); 57 * No parameter. 58 * 59 * Both three macros shall terminate the calling process. 60 * The testcase shall not terminate in any other maneer. 61 * 62 * The other file defines the functions 63 * void output_init() 64 * void output(char * string, ...) 65 * 66 * Those may be used to output information. 67 */ 68 69/********************************************************************************************/ 70/********************************** Configuration ******************************************/ 71/********************************************************************************************/ 72#ifndef VERBOSE 73#define VERBOSE 1 74#endif 75 76#define NTHREADS 30 77 78/********************************************************************************************/ 79/*********************************** Test case *****************************************/ 80/********************************************************************************************/ 81 82int control; 83pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 84 85void my_init( void ) 86{ 87 int ret = 0; 88 ret = pthread_mutex_lock( &mtx ); 89 90 if ( ret != 0 ) 91 { 92 UNRESOLVED( ret, "Failed to lock mutex in initializer" ); 93 } 94 95 control++; 96 97 ret = pthread_mutex_unlock( &mtx ); 98 99 if ( ret != 0 ) 100 { 101 UNRESOLVED( ret, "Failed to unlock mutex in initializer" ); 102 } 103 104 return ; 105} 106 107/* Thread function */ 108void * threaded ( void * arg ) 109{ 110 int ret; 111 112 ret = pthread_once( arg, my_init ); 113 114 if ( ret != 0 ) 115 { 116 UNRESOLVED( ret, "pthread_once failed" ); 117 } 118 119 return NULL; 120} 121 122/* The main test function. */ 123int main( int argc, char * argv[] ) 124{ 125 int ret, i; 126 127 pthread_once_t myctl = PTHREAD_ONCE_INIT; 128 129 pthread_t th[ NTHREADS ]; 130 131 /* Initialize output */ 132 output_init(); 133 134 control = 0; 135 136 /* Create the children */ 137 138 for ( i = 0; i < NTHREADS; i++ ) 139 { 140 ret = pthread_create( &th[ i ], NULL, threaded, &myctl ); 141 142 if ( ret != 0 ) 143 { 144 UNRESOLVED( ret, "Failed to create a thread" ); 145 } 146 } 147 148 /* Then join */ 149 for ( i = 0; i < NTHREADS; i++ ) 150 { 151 ret = pthread_join( th[ i ], NULL ); 152 153 if ( ret != 0 ) 154 { 155 UNRESOLVED( ret, "Failed to join a thread" ); 156 } 157 } 158 159 /* Fetch the memory */ 160 ret = pthread_mutex_lock( &mtx ); 161 162 if ( ret != 0 ) 163 { 164 UNRESOLVED( ret, "Failed to lock mutex in initializer" ); 165 } 166 167 if ( control != 1 ) 168 { 169 output( "Control: %d\n", control ); 170 FAILED( "The initializer function did not execute once" ); 171 } 172 173 ret = pthread_mutex_unlock( &mtx ); 174 175 if ( ret != 0 ) 176 { 177 UNRESOLVED( ret, "Failed to unlock mutex in initializer" ); 178 } 179 180 PASSED; 181} 182 183 184