44#include "MagickCore/studio.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/memory_.h"
48#include "MagickCore/memory-private.h"
49#include "MagickCore/mutex.h"
50#include "MagickCore/semaphore.h"
51#include "MagickCore/semaphore-private.h"
52#include "MagickCore/string_.h"
53#include "MagickCore/thread_.h"
54#include "MagickCore/thread-private.h"
55#include "MagickCore/utility-private.h"
98MagickExport
void ActivateSemaphoreInfo(
SemaphoreInfo **semaphore_info)
105 *semaphore_info=AcquireSemaphoreInfo();
129static void *AcquireSemaphoreMemory(
const size_t count,
const size_t quantum)
131#define AlignedExtent(size,alignment) \
132 (((size)+((alignment)-1)) & (size_t) ~((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;
178static 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);
293MagickExport
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++;
351MagickExport
void RelinquishSemaphoreInfo(
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);
398MagickPrivate MagickBooleanType SemaphoreComponentGenesis(
void)
400 InitializeMagickMutex();
422MagickPrivate
void SemaphoreComponentTerminus(
void)
424 DestroyMagickMutex();
449MagickExport
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);