• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *
4  * --------------------------------------------------------------------------
5  *
6  *      Pthreads-win32 - POSIX Threads Library for Win32
7  *      Copyright(C) 1998 John E. Bossom
8  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
9  *
10  *      Contact Email: rpj@callisto.canberra.edu.au
11  *
12  *      The current list of contributors is contained
13  *      in the file CONTRIBUTORS included with the source
14  *      code distribution. The list can also be seen at the
15  *      following World Wide Web location:
16  *      http://sources.redhat.com/pthreads-win32/contributors.html
17  *
18  *      This library is free software; you can redistribute it and/or
19  *      modify it under the terms of the GNU Lesser General Public
20  *      License as published by the Free Software Foundation; either
21  *      version 2 of the License, or (at your option) any later version.
22  *
23  *      This library is distributed in the hope that it will be useful,
24  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26  *      Lesser General Public License for more details.
27  *
28  *      You should have received a copy of the GNU Lesser General Public
29  *      License along with this library in the file COPYING.LIB;
30  *      if not, write to the Free Software Foundation, Inc.,
31  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
32  *
33  */
34 
35 #include "../include/pthread.h"
36 //#include "sched.h"
37 //#include "semaphore.h"
38 #include <windows.h>
39 #include <stdio.h>
40 
41 #ifdef __GNUC__
42 #include <stdlib.h>
43 #endif
44 
45 #include "benchtest.h"
46 
47 int old_mutex_use = OLD_WIN32CS;
48 
49 BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;
50 HINSTANCE ptw32_h_kernel32;
51 
52 void
dummy_call(int * a)53 dummy_call(int * a)
54 {
55 }
56 
57 void
interlocked_inc_with_conditionals(int * a)58 interlocked_inc_with_conditionals(int * a)
59 {
60   if (a != NULL)
61     if (InterlockedIncrement((long *) a) == -1)
62       {
63         *a = 0;
64       }
65 }
66 
67 void
interlocked_dec_with_conditionals(int * a)68 interlocked_dec_with_conditionals(int * a)
69 {
70   if (a != NULL)
71     if (InterlockedDecrement((long *) a) == -1)
72       {
73         *a = 0;
74       }
75 }
76 
77 int
old_mutex_init(old_mutex_t * mutex,const old_mutexattr_t * attr)78 old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr)
79 {
80   int result = 0;
81   old_mutex_t mx;
82 
83   if (mutex == NULL)
84     {
85       return EINVAL;
86     }
87 
88   mx = (old_mutex_t) calloc(1, sizeof(*mx));
89 
90   if (mx == NULL)
91     {
92       result = ENOMEM;
93       goto FAIL0;
94     }
95 
96   mx->mutex = 0;
97 
98   if (attr != NULL
99       && *attr != NULL
100       && (*attr)->pshared == PTHREAD_PROCESS_SHARED
101       )
102     {
103       result = ENOSYS;
104     }
105   else
106     {
107         CRITICAL_SECTION cs;
108 
109         /*
110          * Load KERNEL32 and try to get address of TryEnterCriticalSection
111          */
112         ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
113         ptw32_try_enter_critical_section = (BOOL (WINAPI *)(LPCRITICAL_SECTION))
114 
115 #if defined(NEED_UNICODE_CONSTS)
116         GetProcAddress(ptw32_h_kernel32,
117                        (const TCHAR *)TEXT("TryEnterCriticalSection"));
118 #else
119         GetProcAddress(ptw32_h_kernel32,
120                        (LPCSTR) "TryEnterCriticalSection");
121 #endif
122 
123         if (ptw32_try_enter_critical_section != NULL)
124           {
125             InitializeCriticalSection(&cs);
126             if ((*ptw32_try_enter_critical_section)(&cs))
127               {
128                 LeaveCriticalSection(&cs);
129               }
130             else
131               {
132                 /*
133                  * Not really supported (Win98?).
134                  */
135                 ptw32_try_enter_critical_section = NULL;
136               }
137             DeleteCriticalSection(&cs);
138           }
139 
140         if (ptw32_try_enter_critical_section == NULL)
141           {
142             (void) FreeLibrary(ptw32_h_kernel32);
143             ptw32_h_kernel32 = 0;
144           }
145 
146       if (old_mutex_use == OLD_WIN32CS)
147 	{
148 	  InitializeCriticalSection(&mx->cs);
149 	}
150       else if (old_mutex_use == OLD_WIN32MUTEX)
151       {
152 	  mx->mutex = CreateMutex (NULL,
153 				   FALSE,
154 				   NULL);
155 
156 	  if (mx->mutex == 0)
157 	    {
158 	      result = EAGAIN;
159 	    }
160 	}
161       else
162 	{
163         result = EINVAL;
164       }
165     }
166 
167   if (result != 0 && mx != NULL)
168     {
169       free(mx);
170       mx = NULL;
171     }
172 
173 FAIL0:
174   *mutex = mx;
175 
176   return(result);
177 }
178 
179 
180 int
old_mutex_lock(old_mutex_t * mutex)181 old_mutex_lock(old_mutex_t *mutex)
182 {
183   int result = 0;
184   old_mutex_t mx;
185 
186   if (mutex == NULL || *mutex == NULL)
187     {
188       return EINVAL;
189     }
190 
191   if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
192     {
193       /*
194        * Don't use initialisers when benchtesting.
195        */
196       result = EINVAL;
197     }
198 
199   mx = *mutex;
200 
201   if (result == 0)
202     {
203       if (mx->mutex == 0)
204 	{
205 	  EnterCriticalSection(&mx->cs);
206 	}
207       else
208 	{
209 	  result = (WaitForSingleObject(mx->mutex, INFINITE)
210 		    == WAIT_OBJECT_0)
211 	    ? 0
212 	    : EINVAL;
213 	}
214     }
215 
216   return(result);
217 }
218 
219 int
old_mutex_unlock(old_mutex_t * mutex)220 old_mutex_unlock(old_mutex_t *mutex)
221 {
222   int result = 0;
223   old_mutex_t mx;
224 
225   if (mutex == NULL || *mutex == NULL)
226     {
227       return EINVAL;
228     }
229 
230   mx = *mutex;
231 
232   if (mx != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
233     {
234       if (mx->mutex == 0)
235 	{
236 	  LeaveCriticalSection(&mx->cs);
237 	}
238       else
239 	{
240 	  result = (ReleaseMutex (mx->mutex) ? 0 : EINVAL);
241 	}
242     }
243   else
244     {
245       result = EINVAL;
246     }
247 
248   return(result);
249 }
250 
251 
252 int
old_mutex_trylock(old_mutex_t * mutex)253 old_mutex_trylock(old_mutex_t *mutex)
254 {
255   int result = 0;
256   old_mutex_t mx;
257 
258   if (mutex == NULL || *mutex == NULL)
259     {
260       return EINVAL;
261     }
262 
263   if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
264     {
265       /*
266        * Don't use initialisers when benchtesting.
267        */
268       result = EINVAL;
269     }
270 
271   mx = *mutex;
272 
273   if (result == 0)
274     {
275       if (mx->mutex == 0)
276 	{
277 	  if (ptw32_try_enter_critical_section == NULL)
278           {
279             result = 0;
280           }
281         else if ((*ptw32_try_enter_critical_section)(&mx->cs) != TRUE)
282 	    {
283 	      result = EBUSY;
284 	    }
285 	}
286       else
287 	{
288 	  DWORD status;
289 
290 	  status = WaitForSingleObject (mx->mutex, 0);
291 
292 	  if (status != WAIT_OBJECT_0)
293 	    {
294 	      result = ((status == WAIT_TIMEOUT)
295 			? EBUSY
296 			: EINVAL);
297 	    }
298 	}
299     }
300 
301   return(result);
302 }
303 
304 
305 int
old_mutex_destroy(old_mutex_t * mutex)306 old_mutex_destroy(old_mutex_t *mutex)
307 {
308   int result = 0;
309   old_mutex_t mx;
310 
311   if (mutex == NULL
312       || *mutex == NULL)
313     {
314       return EINVAL;
315     }
316 
317   if (*mutex != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
318     {
319       mx = *mutex;
320 
321       if ((result = old_mutex_trylock(&mx)) == 0)
322         {
323           *mutex = NULL;
324 
325           (void) old_mutex_unlock(&mx);
326 
327           if (mx->mutex == 0)
328             {
329               DeleteCriticalSection(&mx->cs);
330             }
331           else
332             {
333               result = (CloseHandle (mx->mutex) ? 0 : EINVAL);
334             }
335 
336           if (result == 0)
337             {
338               mx->mutex = 0;
339               free(mx);
340             }
341           else
342             {
343               *mutex = mx;
344             }
345         }
346     }
347   else
348     {
349       result = EINVAL;
350     }
351 
352   if (ptw32_try_enter_critical_section != NULL)
353     {
354       (void) FreeLibrary(ptw32_h_kernel32);
355       ptw32_h_kernel32 = 0;
356     }
357 
358   return(result);
359 }
360 
361 /****************************************************************************************/
362