MagickCore 7.0.10
semaphore.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% SSSSS EEEEE M M AAA PPPP H H OOO RRRR EEEEE %
7% SS E MM MM A A P P H H O O R R E %
8% SSS EEE M M M AAAAA PPPP HHHHH O O RRRR EEE %
9% SS E M M A A P H H O O R R E %
10% SSSSS EEEEE M M A A P H H OOO R R EEEEE %
11% %
12% %
13% WizardCore Semaphore Methods %
14% %
15% Software Design %
16% William Radcliffe %
17% Cristy %
18% June 2000 %
19% %
20% %
21% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
22% dedicated to making software imaging solutions freely available. %
23% %
24% You may not use this file except in compliance with the License. You may %
25% obtain a copy of the License at %
26% %
27% https://imagemagick.org/script/license.php %
28% %
29% Unless required by applicable law or agreed to in writing, software %
30% distributed under the License is distributed on an "AS IS" BASIS, %
31% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32% See the License for the specific language governing permissions and %
33% limitations under the License. %
34% %
35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
44#include "wizard/studio.h"
45#include "wizard/exception.h"
47#include "wizard/memory_.h"
49#include "wizard/semaphore.h"
51#include "wizard/string_.h"
52#include "wizard/thread_.h"
55
56/*
57 Struct declaractions.
58*/
60{
63
66
67 ssize_t
69
70 size_t
72};
73
74/*
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76% %
77% %
78% %
79% A c q u i r e S e m a p h o r e I n f o %
80% %
81% %
82% %
83%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84%
85% AcquireSemaphoreInfo() initializes the SemaphoreInfo structure.
86%
87% The format of the AcquireSemaphoreInfo method is:
88%
89% SemaphoreInfo *AcquireSemaphoreInfo(void)
90%
91*/
92
93static void *AcquireSemaphoreMemory(const size_t count,const size_t quantum)
94{
95#define AlignedExtent(size,alignment) \
96 (((size)+((alignment)-1)) & ~((alignment)-1))
97
98 size_t
99 alignment,
100 extent,
101 size;
102
103 void
104 *memory;
105
106 size=count*quantum;
107 if ((count == 0) || (quantum != (size/count)))
108 {
109 errno=ENOMEM;
110 return((void *) NULL);
111 }
112 memory=NULL;
113 alignment=CACHE_LINE_SIZE;
114 extent=AlignedExtent(size,CACHE_LINE_SIZE);
115 if ((size == 0) || (extent < size))
116 return((void *) NULL);
117#if defined(WIZARDSTOOLKIT_HAVE_POSIX_MEMALIGN)
118 if (posix_memalign(&memory,alignment,extent) != 0)
119 memory=NULL;
120#elif defined(WIZARDSTOOLKIT_HAVE__ALIGNED_MALLOC)
121 memory=_aligned_malloc(extent,alignment);
122#else
123 {
124 void
125 *p;
126
127 extent=(size+alignment-1)+sizeof(void *);
128 if (extent > size)
129 {
130 p=malloc(extent);
131 if (p != NULL)
132 {
133 memory=(void *) AlignedExtent((size_t) p+sizeof(void *),alignment);
134 *((void **) memory-1)=p;
135 }
136 }
137 }
138#endif
139 return(memory);
140}
141
142static void *RelinquishSemaphoreMemory(void *memory)
143{
144 if (memory == (void *) NULL)
145 return((void *) NULL);
146#if defined(WIZARDSTOOLKIT_HAVE_POSIX_MEMALIGN)
147 free(memory);
148#elif defined(WIZARDSTOOLKIT_HAVE__ALIGNED_MALLOC)
149 _aligned_free(memory);
150#else
151 free(*((void **) memory-1));
152#endif
153 return(NULL);
154}
155
157{
159 *semaphore_info;
160
161 /*
162 Allocate semaphore.
163 */
164 semaphore_info=(SemaphoreInfo *) AcquireSemaphoreMemory(1,
165 sizeof(*semaphore_info));
166 if (semaphore_info == (SemaphoreInfo *) NULL)
167 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
168 (void) memset(semaphore_info,0,sizeof(SemaphoreInfo));
169 /*
170 Initialize the semaphore.
171 */
172#if defined(WIZARDSTOOLKIT_OPENMP_SUPPORT)
173 omp_init_lock((omp_lock_t *) &semaphore_info->mutex);
174#elif defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
175 {
176 int
177 status;
178
179 pthread_mutexattr_t
180 mutex_info;
181
182 status=pthread_mutexattr_init(&mutex_info);
183 if (status != 0)
184 {
185 errno=status;
186 perror("unable to initialize mutex attributes");
187 _exit(1);
188 }
189 status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
190 if (status != 0)
191 {
192 errno=status;
193 perror("unable to initialize mutex");
194 _exit(1);
195 }
196 status=pthread_mutexattr_destroy(&mutex_info);
197 if (status != 0)
198 {
199 errno=status;
200 perror("unable to destroy mutex");
201 _exit(1);
202 }
203 }
204#elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
205 {
206 int
207 status;
208
209 status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x400);
210 if (status == 0)
211 {
212 errno=status;
213 perror("unable to initialize critical section");
214 _exit(1);
215 }
216 }
217#endif
218 semaphore_info->id=GetWizardThreadId();
219 semaphore_info->reference_count=0;
220 semaphore_info->signature=WizardSignature;
221 return(semaphore_info);
222}
223
224/*
225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226% %
227% %
228% %
229% A c t i v a t e S e m a p h o r e I n f o %
230% %
231% %
232% %
233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234%
235% ActivateSemaphoreInfo() activates a semaphore under protection of a mutex
236% to ensure only one thread allocates the semaphore.
237%
238% The format of the ActivateSemaphoreInfo method is:
239%
240% void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
241%
242% A description of each parameter follows:
243%
244% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
245%
246*/
248{
249 assert(semaphore_info != (SemaphoreInfo **) NULL);
250 if (*semaphore_info == (SemaphoreInfo *) NULL)
251 {
254 if (*semaphore_info == (SemaphoreInfo *) NULL)
255 *semaphore_info=AcquireSemaphoreInfo();
257 }
258}
259
260/*
261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262% %
263% %
264% %
265% L o c k S e m a p h o r e I n f o %
266% %
267% %
268% %
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270%
271% LockSemaphoreInfo() locks a semaphore.
272%
273% The format of the LockSemaphoreInfo method is:
274%
275% void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
276%
277% A description of each parameter follows:
278%
279% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
280%
281*/
283{
284 assert(semaphore_info != (SemaphoreInfo *) NULL);
285 assert(semaphore_info->signature == WizardSignature);
286#if defined(WIZARDSTOOLKIT_OPENMP_SUPPORT)
287 omp_set_lock((omp_lock_t *) &semaphore_info->mutex);
288#elif defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
289 {
290 int
291 status;
292
293 status=pthread_mutex_lock(&semaphore_info->mutex);
294 if (status != 0)
295 {
296 errno=status;
297 perror("unable to lock mutex");
298 _exit(1);
299 }
300 }
301#elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
302 EnterCriticalSection(&semaphore_info->mutex);
303#endif
304#if defined(WIZARDSTOOLKIT_DEBUG)
305 if ((semaphore_info->reference_count > 0) &&
306 (IsWizardThreadEqual(semaphore_info->id) != WizardFalse))
307 {
308 perror("unexpected recursive lock!");
309 _exit(1);
310 }
311#endif
312 semaphore_info->id=GetWizardThreadId();
313 semaphore_info->reference_count++;
314}
315
316/*
317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318% %
319% %
320% %
321% R e l i n q u i s h S e m a p h o r e I n f o %
322% %
323% %
324% %
325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326%
327% RelinquishSemaphoreInfo() destroys a semaphore.
328%
329% The format of the RelinquishSemaphoreInfo method is:
330%
331% void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
332%
333% A description of each parameter follows:
334%
335% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
336%
337*/
339{
340 assert(semaphore_info != (SemaphoreInfo **) NULL);
341 assert((*semaphore_info) != (SemaphoreInfo *) NULL);
342 assert((*semaphore_info)->signature == WizardSignature);
345#if defined(WIZARDSTOOLKIT_OPENMP_SUPPORT)
346 omp_destroy_lock((omp_lock_t *) &(*semaphore_info)->mutex);
347#elif defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
348 {
349 int
350 status;
351
352 status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
353 if (status != 0)
354 {
355 errno=status;
356 perror("unable to destroy mutex");
357 _exit(1);
358 }
359 }
360#elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
361 DeleteCriticalSection(&(*semaphore_info)->mutex);
362#endif
363 (*semaphore_info)->signature=(~WizardSignature);
364 *semaphore_info=(SemaphoreInfo *) RelinquishSemaphoreMemory(*semaphore_info);
366}
367
368/*
369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370% %
371% %
372% %
373% S e m a p h o r e C o m p o n e n t G e n e s i s %
374% %
375% %
376% %
377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378%
379% SemaphoreComponentGenesis() instantiates the semaphore component.
380%
381% The format of the SemaphoreComponentGenesis method is:
382%
383% WizardBooleanType SemaphoreComponentGenesis(void)
384%
385*/
387{
389 return(WizardTrue);
390}
391
392/*
393%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394% %
395% %
396% %
397% S e m a p h o r e C o m p o n e n t T e r m i n u s %
398% %
399% %
400% %
401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402%
403% SemaphoreComponentTerminus() destroys the semaphore environment.
404%
405% The format of the SemaphoreComponentTerminus method is:
406%
407% SemaphoreComponentTerminus(void)
408%
409*/
411{
413}
414
415/*
416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
417% %
418% %
419% %
420% U n l o c k S e m a p h o r e I n f o %
421% %
422% %
423% %
424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425%
426% UnlockSemaphoreInfo() unlocks a semaphore.
427%
428% The format of the UnlockSemaphoreInfo method is:
429%
430% void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
431%
432% A description of each parameter follows:
433%
434% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
435%
436*/
438{
439 assert(semaphore_info != (SemaphoreInfo *) NULL);
440 assert(semaphore_info->signature == WizardSignature);
441#if defined(WIZARDSTOOLKIT_DEBUG)
442 assert(IsWizardThreadEqual(semaphore_info->id) != WizardFalse);
443 if (semaphore_info->reference_count == 0)
444 {
445 (void) fprintf(stderr,"Warning: semaphore lock already unlocked!\n");
446 (void) fflush(stderr);
447 return;
448 }
449 semaphore_info->reference_count--;
450#endif
451#if defined(WIZARDSTOOLKIT_OPENMP_SUPPORT)
452 omp_unset_lock((omp_lock_t *) &semaphore_info->mutex);
453#elif defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
454 {
455 int
456 status;
457
458 status=pthread_mutex_unlock(&semaphore_info->mutex);
459 if (status != 0)
460 {
461 errno=status;
462 perror("unable to unlock mutex");
463 _exit(1);
464 }
465 }
466#elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
467 LeaveCriticalSection(&semaphore_info->mutex);
468#endif
469}
#define ThrowFatalException(severity, tag)
@ ResourceFatalError
Definition exception.h:121
static size_t GetWizardThreadId(void)
Definition file.c:116
#define CACHE_LINE_SIZE
#define WizardExport
#define WizardSignature
static void DestroyWizardMutex(void)
static void InitializeWizardMutex(void)
static void UnlockWizardMutex(void)
static void LockWizardMutex(void)
WizardExport void SemaphoreComponentTerminus(void)
Definition semaphore.c:410
WizardExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:338
WizardExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition semaphore.c:156
static void * RelinquishSemaphoreMemory(void *memory)
Definition semaphore.c:142
WizardExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:282
WizardExport WizardBooleanType SemaphoreComponentGenesis(void)
Definition semaphore.c:386
WizardExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:437
static void * AcquireSemaphoreMemory(const size_t count, const size_t quantum)
Definition semaphore.c:93
WizardExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:247
#define AlignedExtent(size, alignment)
ssize_t reference_count
Definition semaphore.c:68
size_t signature
Definition semaphore.c:71
WizardMutexType mutex
Definition semaphore.c:62
WizardThreadType id
Definition semaphore.c:65
static WizardBooleanType IsWizardThreadEqual(const WizardThreadType id)
size_t WizardMutexType
pid_t WizardThreadType
Definition thread_.h:30
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27