Don't use POSIX fnmatch() for pattern matching.
[gromacs/qmmm-gamess-us.git] / src / gmxlib / thread_mpi / nothreads.c
blob529a9ed7de85ebe98ea54a391200c6444765690d
1 /*
2 This source code file is part of thread_mpi.
3 Written by Sander Pronk, Erik Lindahl, and possibly others.
5 Copyright (c) 2009, Sander Pronk, Erik Lindahl.
6 All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1) Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3) Neither the name of the copyright holders nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 If you want to redistribute modifications, please consider that
31 scientific software is very special. Version control is crucial -
32 bugs must be traceable. We will be happy to consider code for
33 inclusion in the official distribution, but derived work should not
34 be called official thread_mpi. Details are found in the README & COPYING
35 files.
37 To help us fund development, we humbly ask that you cite
38 any papers on the package - you can find them in the top README file.
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
46 /* Hide this implementation from Doxygen, since it conflicts with pthreads */
47 #ifndef DOXYGEN
49 #if ! (defined(THREAD_PTHREADS) || defined(THREAD_WINDOWS))
51 #include "thread_mpi/thread.h"
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
58 #include <stdlib.h>
59 #include <stdio.h>
60 #include <errno.h>
62 #include "tMPI_Fatal_error.h"
64 /* Number of thread-specific storage elements.
66 * It might seem stupid to make the length constant instead of dynamic,
67 * but e.g. the Pthreads standard only guarantees 128 key entries, so for
68 * portability we shouldn't use more.
69 */
70 #define TMPI_THREAD_NOTHREADS_NSPECIFICDATA 128
74 * Static variables used to keep track of thread-private data
75 * when we are compiling without thread support. This is actually quite
76 * simple - we just keep a list of structures with the value (pointer)
77 * and destructor.
80 static struct
82 int used; /*!< 1 if this element is used, 0 if it is free */
83 void * value; /*!< Pointer to the specific data for key n */
84 void (*destructor)(void *); /*!< Pointer to destructor function for key n */
86 tMPI_Thread_nothreads_specificdata[TMPI_THREAD_NOTHREADS_NSPECIFICDATA];
89 /*! \brief flag to determine if static key storage has been initialized.
91 static int
92 tMPI_Thread_nothreads_specific_init_done = 0;
96 /* Dummy implementation of abstract thread datatype */
97 struct tMPI_Thread
99 int locked; /* Just useful for debugging */
105 /* Dummy implementation of abstract thread-specific data key type */
106 struct tMPI_Thread_key
108 int index; /*!< Index into our static list of private data */
114 enum tMPI_Thread_support
115 tMPI_Thread_support(void)
117 return TMPI_THREAD_SUPPORT_NO;
123 tMPI_Thread_create (tMPI_Thread_t * thread,
124 void * (*start_routine)(void *),
125 void * arg)
127 tMPI_Fatal_error(FARGS,"Cannot start threads without thread support.\n");
129 return 0;
135 tMPI_Thread_join (tMPI_Thread_t thread,
136 void ** value_ptr)
138 tMPI_Fatal_error(FARGS,"Cannot join threads without thread support.\n");
140 return 0;
147 tMPI_Thread_mutex_init(tMPI_Thread_mutex_t *mtx)
149 if(mtx==NULL)
151 return EINVAL;
154 /* We use an integer as a mutex for debugging. */
155 mtx->actual_mutex = malloc(sizeof(int));
157 if(mtx->actual_mutex==NULL)
159 fprintf(stderr,
160 "error [%s, line %d]: Failed to allocate mutex memory.\n",
161 __FILE__,__LINE__);
162 fflush(stderr);
163 return ENOMEM;
166 * ( (int *) (mtx->actual_mutex) ) = 0; /* Unlocked */
168 mtx->status = TMPI_THREAD_ONCE_STATUS_READY;
170 return 0;
176 tMPI_Thread_mutex_destroy(tMPI_Thread_mutex_t *mtx)
178 if(mtx == NULL)
180 return EINVAL;
183 /* Must use system free() since memory allocation depends on
184 * messages and threads working.
186 free(mtx->actual_mutex);
188 return 0;
194 static int
195 tMPI_Thread_mutex_init_once(tMPI_Thread_mutex_t *mtx)
197 int rc;
198 /* No threads = nothing to worry about */
199 if(mtx->status != TMPI_THREAD_ONCE_STATUS_READY)
200 rc = tMPI_Thread_mutex_init(mtx);
201 else
202 rc = 0;
204 return rc;
210 tMPI_Thread_mutex_lock(tMPI_Thread_mutex_t *mtx)
212 /* Ccheck whether this mutex is initialized */
213 if(mtx->status != TMPI_THREAD_ONCE_STATUS_READY)
215 tMPI_Thread_mutex_init_once(mtx);
218 /* The mutex is now guaranteed to be valid. */
219 * ( (int *) (mtx->actual_mutex) ) = 1;
221 return 0;
228 tMPI_Thread_mutex_trylock(tMPI_Thread_mutex_t *mtx)
230 int ret;
231 int *p;
233 /* Ccheck whether this mutex is initialized */
234 if(mtx->status != TMPI_THREAD_ONCE_STATUS_READY)
236 tMPI_Thread_mutex_init_once(mtx);
239 p = (int *) (mtx->actual_mutex);
241 if( *p == 0 )
243 *p = 1;
244 ret = 0;
246 else
248 ret = EBUSY;
251 return ret;
257 tMPI_Thread_mutex_unlock(tMPI_Thread_mutex_t *mtx)
259 * ( (int *) (mtx->actual_mutex) ) = 0; /* Unlocked */
261 return 0;
267 tMPI_Thread_key_create(tMPI_Thread_key_t * key,
268 void (*destructor)(void *))
270 int i;
272 if(key==NULL)
274 fprintf(stderr,
275 "error [%s, line %d]: Invalid key pointer.\n",
276 __FILE__,__LINE__);
277 fflush(stderr);
278 return EINVAL;
282 * Allocate memory for the pthread key. We must use the system malloc
283 * here since the other memory allocation depends on tMPI_Thread.h.
285 *key = malloc(sizeof(struct tMPI_Thread_key));
287 if(*key==NULL)
289 fprintf(stderr,
290 "error [%s, line %d]: Failed to allocate thread key memory.\n",
291 __FILE__,__LINE__);
292 fflush(stderr);
293 return ENOMEM;
296 if( tMPI_Thread_nothreads_specific_init_done == 0)
299 for(i=0;i<TMPI_THREAD_NOTHREADS_NSPECIFICDATA;i++)
301 tMPI_Thread_nothreads_specificdata[i].used = 0;
302 tMPI_Thread_nothreads_specificdata[i].value = NULL;
303 tMPI_Thread_nothreads_specificdata[i].destructor = NULL;
306 tMPI_Thread_nothreads_specific_init_done = 1;
309 /* Try to find an empty spot */
310 for(i=0;i<TMPI_THREAD_NOTHREADS_NSPECIFICDATA;i++)
312 if(tMPI_Thread_nothreads_specificdata[i].used == 0)
313 break;
316 if(i==TMPI_THREAD_NOTHREADS_NSPECIFICDATA)
318 tMPI_Fatal_error(FARGS,"Already used all %d private data keys.\n");
319 return -1;
322 tMPI_Thread_nothreads_specificdata[i].used = 1;
323 (*key)->index = i;
325 return 0;
330 tMPI_Thread_key_delete(tMPI_Thread_key_t key)
332 int i;
333 void * value;
334 void (*destructor)(void *);
336 if ( tMPI_Thread_nothreads_specific_init_done == 0 || key == NULL)
338 return EINVAL;
341 i = key->index;
343 if(tMPI_Thread_nothreads_specificdata[i].value != NULL)
345 destructor = tMPI_Thread_nothreads_specificdata[i].destructor;
346 value = tMPI_Thread_nothreads_specificdata[i].value;
347 (*destructor)(value);
350 free(key);
352 return 0;
357 void *
358 tMPI_Thread_getspecific(tMPI_Thread_key_t key)
360 if ( tMPI_Thread_nothreads_specific_init_done == 0 || key == NULL)
362 return NULL;
365 return tMPI_Thread_nothreads_specificdata[key->index].value;
370 tMPI_Thread_setspecific(tMPI_Thread_key_t key,
371 void * value)
374 if ( tMPI_Thread_nothreads_specific_init_done == 0 || key == NULL)
376 return EINVAL;
379 tMPI_Thread_nothreads_specificdata[key->index].value = value;
381 return 0;
387 tMPI_Thread_once(tMPI_Thread_once_t * once_control,
388 void (*init_routine)(void))
390 if(once_control->status != TMPI_THREAD_ONCE_STATUS_READY)
392 (*init_routine)();
393 once_control->status = TMPI_THREAD_ONCE_STATUS_READY;
396 return 0;
404 tMPI_Thread_cond_init(tMPI_Thread_cond_t * cond)
406 int ret;
408 /* Condition variables are completely useless without threads, since
409 * we cannot wait for some signal to happen if we are the only thread
410 * executing.
412 * Still, as long as we don't try to call the wait routine it won't hurt,
413 * and we want the contents to be clean for debugging.
415 cond->actual_cond = NULL;
416 cond->status = TMPI_THREAD_ONCE_STATUS_READY;
418 return 0;
423 tMPI_Thread_cond_destroy(tMPI_Thread_cond_t * cond)
425 if(cond == NULL)
427 return EINVAL;
430 return 0;
436 static int
437 tMPI_Thread_cond_init_once(tMPI_Thread_cond_t * cond)
439 /* No threads = nothing to worry about */
440 if(cond->status != TMPI_THREAD_ONCE_STATUS_READY)
441 return tMPI_Thread_cond_init(cond);
447 tMPI_Thread_cond_wait(tMPI_Thread_cond_t * cond,
448 tMPI_Thread_mutex_t * mtx)
450 tMPI_Fatal_error(FARGS,"Called tMPI_Thread_cond_wait() without thread support. This is a major\n"
451 "error, since nobody else can signal the condition variable - exiting.\n");
453 return 0;
460 tMPI_Thread_cond_broadcast(tMPI_Thread_cond_t * cond)
462 tMPI_Fatal_error(FARGS,"Called tMPI_Thread_broadcast() without thread support.\n");
464 return 0;
470 void
471 tMPI_Thread_exit(void * value_ptr)
473 tMPI_Fatal_error(FARGS,"Called tMPI_Thread_exit() without thread support.\n");
480 tMPI_Thread_cancel(tMPI_Thread_t thread)
482 tMPI_Fatal_error(FARGS,"Called tMPI_Thread_cancel() without thread support.\n");
484 return 0;
490 tMPI_Thread_barrier_init(tMPI_Thread_barrier_t * barrier,
491 int n)
493 /* Barriers don't do anything without multiple threads */
494 return 0;
499 tMPI_Thread_barrier_destroy(tMPI_Thread_barrier_t * barrier)
501 /* Barriers don't do anything without multiple threads */
502 return 0;
507 tMPI_Thread_barrier_wait(tMPI_Thread_barrier_t * barrier)
509 /* Barriers don't do anything without multiple threads.
510 * Since we are the only thread we're the master!
512 return -1;
518 void
519 tMPI_lockfile(FILE * stream)
521 /* Nothing to worry about without threads */
522 return;
526 void
527 tMPI_unlockfile(FILE * stream)
529 /* Nothing to worry about without threads */
530 return;
536 #endif /* ifndef DOXYGEN */
538 #endif /* no threads */