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