BRL-CAD
semaphore.c
Go to the documentation of this file.
1 /* S E M A P H O R E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <math.h>
27 
28 #include "bio.h"
29 #include "bu/log.h"
30 #include "bu/malloc.h"
31 #include "bu/parallel.h"
32 
33 /*
34  * multithreading support for SunOS 5.X / Solaris 2.x
35  */
36 #if defined(SUNOS) && SUNOS >= 52
37 # include <sys/unistd.h>
38 # include <thread.h>
39 # include <synch.h>
40 # define SEMAPHORE_INIT DEFAULEMUTEX
41 struct bu_semaphores {
42  uint32_t magic;
43  mutex_t mu;
44 };
45 # define DEFINED_BU_SEMAPHORES 1
46 
47 /*
48  * multithread support built on POSIX Threads (pthread) library.
49  */
50 #elif defined(HAVE_PTHREAD_H)
51 # include <pthread.h>
52 # define SEMAPHORE_INIT PTHREAD_MUTEX_INITIALIZER
53 struct bu_semaphores {
54  uint32_t magic;
55  pthread_mutex_t mu;
56 };
57 # define DEFINED_BU_SEMAPHORES 1
58 
59 /*
60  * multithread support based on the Windows kernel.
61  */
62 #elif defined(_WIN32) && !defined(__CYGWIN__)
63 # define SEMAPHORE_INIT {0}
64 struct bu_semaphores {
65  uint32_t magic;
66  CRITICAL_SECTION mu;
67 };
68 # define DEFINED_BU_SEMAPHORES 1
69 #endif
70 
71 #define SEMAPHORE_MAGIC 0x62757365
72 #define SEMAPHORE_MAX 1024
73 
74 
75 #if defined(PARALLEL) || defined(DEFINED_BU_SEMAPHORES)
76 static unsigned int bu_nsemaphores = 0;
77 static struct bu_semaphores bu_semaphores[SEMAPHORE_MAX] = {{0, SEMAPHORE_INIT}};
78 #endif
79 
80 
81 void
82 bu_semaphore_init(unsigned int nsemaphores)
83 {
84 #if !defined(PARALLEL) && !defined(DEFINED_BU_SEMAPHORES)
85  if (nsemaphores) /* quellage */
86  return;
87  return; /* No support on this hardware */
88 #else
89 
90  unsigned int i;
91 
92  if (nsemaphores < 1)
93  nsemaphores = 1;
94  else if (nsemaphores <= bu_nsemaphores)
95  return; /* Already initialized */
96  else if (UNLIKELY(nsemaphores > SEMAPHORE_MAX)) {
97  fprintf(stderr, "bu_semaphore_init(): could not initialize %d semaphores, max is %d\n",
98  nsemaphores, SEMAPHORE_MAX);
99  exit(2); /* cannot call bu_exit() here */
100  }
101 
102  /*
103  * Begin vendor-specific initialization sections.
104  */
105 
106 # if defined(SUNOS)
107  for (i=bu_nsemaphores; i < nsemaphores; i++) {
108  bu_semaphores[i].magic = SEMAPHORE_MAGIC;
109  memset(&bu_semaphores[i].mu, 0, sizeof(struct bu_semaphores));
110  if (mutex_init(&bu_semaphores[i].mu, USYNC_THREAD, NULL)) {
111  fprintf(stderr, "bu_semaphore_init(): mutex_init() failed on [%d]\n", i+1, nsemaphores - bu_nsemaphores);
112  bu_bomb("fatal semaphore acquisition failure");
113  }
114  }
115 # elif defined(HAVE_PTHREAD_H)
116  for (i=bu_nsemaphores; i < nsemaphores; i++) {
117  bu_semaphores[i].magic = SEMAPHORE_MAGIC;
118  memset(&bu_semaphores[i].mu, 0, sizeof(struct bu_semaphores));
119  if (pthread_mutex_init(&bu_semaphores[i].mu, NULL)) {
120  fprintf(stderr, "bu_semaphore_init(): pthread_mutex_init() failed on [%d] of [%d]\n", i+1, nsemaphores - bu_nsemaphores);
121  bu_bomb("fatal semaphore acquisition failure");
122  }
123  }
124 # elif defined(_WIN32) && !defined(__CYGWIN__)
125  for (i=bu_nsemaphores; i < nsemaphores; i++) {
126  bu_semaphores[i].magic = SEMAPHORE_MAGIC;
127  memset(&bu_semaphores[i].mu, 0, sizeof(struct bu_semaphores));
128  /* This cannot fail except for very low memory situations in XP. */
129  InitializeCriticalSection(&bu_semaphores[i].mu);
130  }
131 # endif
132 
133  /*
134  * This should be last thing done before returning, so that
135  * any subroutines called (e.g. bu_calloc()) won't think that
136  * parallel operation has begun yet, and do acquire/release.
137  */
138  bu_nsemaphores = nsemaphores;
139 #endif /* PARALLEL */
140 }
141 
142 
143 void
145 {
146 
147 #if !defined(PARALLEL) && !defined(DEFINED_BU_SEMAPHORES)
148  return; /* No support on this hardware */
149 #else
150 
151  unsigned int i;
152 
153  /* Close out the mutexes already created. */
154 # if defined(SUNOS)
155  for (i = 0; i < bu_nsemaphores; i++) {
156  if (mutex_destroy(&bu_semaphores[i].mu)) {
157  fprintf(stderr, "bu_semaphore_free(): mutex_destroy() failed on [%d] of [%d]\n", i+1, bu_nsemaphores);
158  }
159  }
160 
161 # elif defined(HAVE_PTHREAD_H)
162  for (i = 0; i < bu_nsemaphores; i++) {
163  if (pthread_mutex_destroy(&bu_semaphores[i].mu)) {
164  fprintf(stderr, "bu_semaphore_free(): pthread_mutex_destroy() failed on [%d] of [%d]\n", i+1, bu_nsemaphores);
165  }
166  }
167 
168 # elif defined(_WIN32) && !defined(__CYGWIN__)
169  for (i = 0; i < bu_nsemaphores; i++) {
170  DeleteCriticalSection(&bu_semaphores[i].mu);
171  }
172 # endif
173 
174  bu_nsemaphores = 0;
175 #endif /* PARALLEL */
176 }
177 
178 
179 void
180 bu_semaphore_acquire(unsigned int i)
181 {
182 #if !defined(PARALLEL) && !defined(DEFINED_BU_SEMAPHORES)
183  if (i) /* quellage */
184  return;
185  return; /* No support on this hardware */
186 #else
187 
188  /* ensure we have this semaphore */
189  bu_semaphore_init(i+1);
190  BU_CKMAG(&bu_semaphores[i], SEMAPHORE_MAGIC, "bu_semaphore");
191 
192  /*
193  * Begin vendor-specific initialization sections.
194  */
195 
196 # ifdef SUNOS
197  if (mutex_lock(&bu_semaphores[i].mu)) {
198  fprintf(stderr, "bu_semaphore_acquire(): mutex_lock() failed on [%d]\n", i);
199  bu_bomb("fatal semaphore acquisition failure");
200  }
201 # endif
202 # if defined(HAVE_PTHREAD_H)
203  if (pthread_mutex_lock(&bu_semaphores[i].mu)) {
204  fprintf(stderr, "bu_semaphore_acquire(): pthread_mutex_lock() failed on [%d]\n", i);
205  bu_bomb("fatal semaphore acquisition failure");
206  }
207 # endif
208 # if defined(_WIN32) && !defined(__CYGWIN__)
209  /* This only fails if the timeout exceeds 30 days. */
210  EnterCriticalSection(&bu_semaphores[i].mu);
211 # endif
212 
213 #endif
214 }
215 
216 
217 void
218 bu_semaphore_release(unsigned int i)
219 {
220 #if !defined(PARALLEL) && !defined(DEFINED_BU_SEMAPHORES)
221  if (i) /* quellage */
222  return;
223  return; /* No support on this hardware */
224 #else
225 
226  /* ensure we have this semaphore */
227  bu_semaphore_init(i+1);
228  BU_CKMAG(&bu_semaphores[i], SEMAPHORE_MAGIC, "bu_semaphore");
229 
230  /*
231  * Begin vendor-specific initialization sections.
232  */
233 
234 # ifdef SUNOS
235  if (mutex_unlock(&bu_semaphores[i].mu)) {
236  fprintf(stderr, "bu_semaphore_acquire(): mutex_unlock() failed on [%d]\n", i);
237  bu_bomb("fatal semaphore acquisition failure");
238  }
239 # endif
240 # if defined(HAVE_PTHREAD_H)
241  if (pthread_mutex_unlock(&bu_semaphores[i].mu)) {
242  fprintf(stderr, "bu_semaphore_acquire(): pthread_mutex_unlock() failed on [%d]\n", i);
243  bu_bomb("fatal semaphore acquisition failure");
244  }
245 # endif
246 
247 # if defined(_WIN32) && !defined(__CYGWIN__)
248  LeaveCriticalSection(&bu_semaphores[i].mu);
249 # endif
250 #endif
251 }
252 
253 
254 /*
255  * Local Variables:
256  * mode: C
257  * tab-width: 8
258  * indent-tabs-mode: t
259  * c-file-style: "stroustrup"
260  * End:
261  * ex: shiftwidth=4 tabstop=8
262  */
#define BU_CKMAG(_ptr, _magic, _str)
Definition: magic.h:233
#define SEMAPHORE_MAX
Definition: semaphore.c:72
void bu_semaphore_init(unsigned int nsemaphores)
Definition: semaphore.c:82
void bu_semaphore_acquire(unsigned int i)
Definition: semaphore.c:180
Header file for the BRL-CAD common definitions.
#define SEMAPHORE_MAGIC
Definition: semaphore.c:71
void * memset(void *s, int c, size_t n)
oldeumate l2 magic
Definition: nmg_mod.c:3843
void bu_semaphore_release(unsigned int i)
Definition: semaphore.c:218
void bu_semaphore_free(void)
Definition: semaphore.c:144
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
#define UNLIKELY(expression)
Definition: common.h:282