44 #include "magick/studio.h"
45 #include "magick/exception.h"
46 #include "magick/exception-private.h"
47 #include "magick/memory_.h"
48 #include "magick/memory-private.h"
49 #include "magick/mutex.h"
50 #include "magick/semaphore.h"
51 #include "magick/semaphore-private.h"
52 #include "magick/string_.h"
53 #include "magick/thread_.h"
54 #include "magick/thread-private.h"
55 #include "magick/utility-private.h"
98 MagickExport
void ActivateSemaphoreInfo(
SemaphoreInfo **semaphore_info)
105 *semaphore_info=AllocateSemaphoreInfo();
129 static void *AcquireSemaphoreMemory(
const size_t count,
const size_t quantum)
131 #define AlignedExtent(size,alignment) \
132 (((size)+((alignment)-1)) & ~((alignment)-1))
143 if ((count == 0) || (quantum != (size/count)))
146 return((
void *) NULL);
149 alignment=CACHE_LINE_SIZE;
150 extent=AlignedExtent(size,CACHE_LINE_SIZE);
151 if ((size == 0) || (alignment <
sizeof(
void *)) || (extent < size))
152 return((
void *) NULL);
153 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
154 if (posix_memalign(&memory,alignment,extent) != 0)
156 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
157 memory=_aligned_malloc(extent,alignment);
163 extent=(size+alignment-1)+
sizeof(
void *);
169 memory=(
void *) AlignedExtent((
size_t) p+
sizeof(
void *),alignment);
170 *((
void **) memory-1)=p;
178 static void *RelinquishSemaphoreMemory(
void *memory)
180 if (memory == (
void *) NULL)
181 return((
void *) NULL);
182 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
184 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
185 _aligned_free(memory);
187 free(*((
void **) memory-1));
201 sizeof(*semaphore_info));
203 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
208 #if defined(MAGICKCORE_OPENMP_SUPPORT)
209 omp_init_lock((omp_lock_t *) &semaphore_info->mutex);
210 #elif defined(MAGICKCORE_THREAD_SUPPORT)
218 status=pthread_mutexattr_init(&mutex_info);
222 perror(
"unable to initialize mutex attributes");
225 #if defined(MAGICKCORE_DEBUG)
226 #if defined(PTHREAD_MUTEX_ERRORCHECK)
227 status=pthread_mutex_settype(&mutex_info,PTHREAD_MUTEX_ERRORCHECK);
231 perror(
"unable to set mutex type");
236 status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
240 perror(
"unable to initialize mutex");
243 status=pthread_mutexattr_destroy(&mutex_info);
247 perror(
"unable to destroy mutex attributes");
251 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
256 status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400);
260 perror(
"unable to initialize critical section");
265 semaphore_info->id=GetMagickThreadId();
266 semaphore_info->reference_count=0;
267 semaphore_info->signature=MagickCoreSignature;
268 return(semaphore_info);
293 MagickExport
void LockSemaphoreInfo(
SemaphoreInfo *semaphore_info)
296 assert(semaphore_info->signature == MagickCoreSignature);
297 #if defined(MAGICKCORE_DEBUG)
298 if ((semaphore_info->reference_count > 0) &&
299 (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
301 (void) FormatLocaleFile(stderr,
"Warning: unexpected recursive lock!\n");
302 (void) fflush(stderr);
305 #if defined(MAGICKCORE_OPENMP_SUPPORT)
306 omp_set_lock((omp_lock_t *) &semaphore_info->mutex);
307 #elif defined(MAGICKCORE_THREAD_SUPPORT)
312 status=pthread_mutex_lock(&semaphore_info->mutex);
316 perror(
"unable to lock mutex");
320 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
321 EnterCriticalSection(&semaphore_info->mutex);
323 #if defined(MAGICKCORE_DEBUG)
324 semaphore_info->id=GetMagickThreadId();
325 semaphore_info->reference_count++;
351 MagickExport
void DestroySemaphoreInfo(
SemaphoreInfo **semaphore_info)
355 assert((*semaphore_info)->signature == MagickCoreSignature);
357 #if defined(MAGICKCORE_OPENMP_SUPPORT)
358 omp_destroy_lock((omp_lock_t *) &(*semaphore_info)->mutex);
359 #elif defined(MAGICKCORE_THREAD_SUPPORT)
364 status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
368 perror(
"unable to destroy mutex");
372 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
373 DeleteCriticalSection(&(*semaphore_info)->mutex);
375 (*semaphore_info)->signature=(~MagickCoreSignature);
376 *semaphore_info=(
SemaphoreInfo *) RelinquishSemaphoreMemory(*semaphore_info);
398 MagickExport MagickBooleanType SemaphoreComponentGenesis(
void)
400 InitializeMagickMutex();
422 MagickExport
void SemaphoreComponentTerminus(
void)
424 DestroyMagickMutex();
449 MagickExport
void UnlockSemaphoreInfo(
SemaphoreInfo *semaphore_info)
452 assert(semaphore_info->signature == MagickCoreSignature);
453 #if defined(MAGICKCORE_DEBUG)
454 assert(IsMagickThreadEqual(semaphore_info->id) != MagickFalse);
455 if (semaphore_info->reference_count == 0)
457 (void) FormatLocaleFile(stderr,
458 "Warning: semaphore lock already unlocked!\n");
459 (void) fflush(stderr);
462 semaphore_info->reference_count--;
464 #if defined(MAGICKCORE_OPENMP_SUPPORT)
465 omp_unset_lock((omp_lock_t *) &semaphore_info->mutex);
466 #elif defined(MAGICKCORE_THREAD_SUPPORT)
471 status=pthread_mutex_unlock(&semaphore_info->mutex);
475 perror(
"unable to unlock mutex");
479 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
480 LeaveCriticalSection(&semaphore_info->mutex);