This source file includes following definitions.
- ActivateSemaphoreInfo
- AcquireSemaphoreMemory
- RelinquishSemaphoreMemory
- AllocateSemaphoreInfo
- DestroySemaphoreInfo
- LockSemaphoreInfo
- SemaphoreComponentGenesis
- SemaphoreComponentTerminus
- UnlockSemaphoreInfo
#include "magick/studio.h"
#include "magick/exception.h"
#include "magick/exception-private.h"
#include "magick/memory_.h"
#include "magick/memory-private.h"
#include "magick/semaphore.h"
#include "magick/semaphore-private.h"
#include "magick/string_.h"
#include "magick/thread_.h"
#include "magick/thread-private.h"
struct SemaphoreInfo
{
MagickMutexType
mutex;
MagickThreadType
id;
ssize_t
reference_count;
size_t
signature;
};
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
{
assert(semaphore_info != (SemaphoreInfo **) NULL);
if (*semaphore_info == (SemaphoreInfo *) NULL)
{
InitializeMagickMutex();
LockMagickMutex();
if (*semaphore_info == (SemaphoreInfo *) NULL)
*semaphore_info=AllocateSemaphoreInfo();
UnlockMagickMutex();
}
}
static void *AcquireSemaphoreMemory(const size_t count,const size_t quantum)
{
#define AlignedExtent(size,alignment) \
(((size)+((alignment)-1)) & ~((alignment)-1))
size_t
alignment,
extent,
size;
void
*memory;
size=count*quantum;
if ((count == 0) || (quantum != (size/count)))
{
errno=ENOMEM;
return((void *) NULL);
}
memory=NULL;
alignment=CACHE_LINE_SIZE;
extent=AlignedExtent(size,alignment);
if ((size == 0) || (alignment < sizeof(void *)) || (extent < size))
return((void *) NULL);
#if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
if (posix_memalign(&memory,alignment,extent) != 0)
memory=NULL;
#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
memory=_aligned_malloc(extent,alignment);
#else
{
void
*p;
extent=(size+alignment-1)+sizeof(void *);
if (extent > size)
{
p=malloc(extent);
if (p != NULL)
{
memory=(void *) AlignedExtent((size_t) p+sizeof(void *),alignment);
*((void **) memory-1)=p;
}
}
}
#endif
return(memory);
}
static void *RelinquishSemaphoreMemory(void *memory)
{
if (memory == (void *) NULL)
return((void *) NULL);
#if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
free(memory);
#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
_aligned_free(memory);
#else
free(*((void **) memory-1));
#endif
return(NULL);
}
MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
{
SemaphoreInfo
*semaphore_info;
semaphore_info=(SemaphoreInfo *) AcquireSemaphoreMemory(1,
sizeof(*semaphore_info));
if (semaphore_info == (SemaphoreInfo *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
(void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo));
#if defined(MAGICKCORE_OPENMP_SUPPORT)
omp_init_lock((omp_lock_t *) &semaphore_info->mutex);
#elif defined(MAGICKCORE_THREAD_SUPPORT)
{
int
status;
pthread_mutexattr_t
mutex_info;
status=pthread_mutexattr_init(&mutex_info);
if (status != 0)
{
errno=status;
perror("unable to initialize mutex attributes");
_exit(1);
}
#if defined(MAGICKCORE_DEBUG)
#if defined(PTHREAD_MUTEX_ERRORCHECK)
status=pthread_mutex_settype(&mutex_info,PTHREAD_MUTEX_ERRORCHECK);
if (status != 0)
{
errno=status;
perror("unable to set mutex type");
_exit(1);
}
#endif
#endif
status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
if (status != 0)
{
errno=status;
perror("unable to initialize mutex");
_exit(1);
}
status=pthread_mutexattr_destroy(&mutex_info);
if (status != 0)
{
errno=status;
perror("unable to destroy mutex attributes");
_exit(1);
}
}
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
{
int
status;
status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400);
if (status == 0)
{
errno=status;
perror("unable to initialize critical section");
_exit(1);
}
}
#endif
semaphore_info->id=GetMagickThreadId();
semaphore_info->reference_count=0;
semaphore_info->signature=MagickSignature;
return(semaphore_info);
}
MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
{
assert(semaphore_info != (SemaphoreInfo **) NULL);
assert((*semaphore_info) != (SemaphoreInfo *) NULL);
assert((*semaphore_info)->signature == MagickSignature);
InitializeMagickMutex();
LockMagickMutex();
#if defined(MAGICKCORE_OPENMP_SUPPORT)
omp_destroy_lock((omp_lock_t *) &(*semaphore_info)->mutex);
#elif defined(MAGICKCORE_THREAD_SUPPORT)
{
int
status;
status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
if (status != 0)
{
errno=status;
perror("unable to destroy mutex");
_exit(1);
}
}
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
DeleteCriticalSection(&(*semaphore_info)->mutex);
#endif
(*semaphore_info)->signature=(~MagickSignature);
*semaphore_info=(SemaphoreInfo *) RelinquishSemaphoreMemory(*semaphore_info);
UnlockMagickMutex();
}
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
{
assert(semaphore_info != (SemaphoreInfo *) NULL);
assert(semaphore_info->signature == MagickSignature);
#if defined(MAGICKCORE_DEBUG)
if ((semaphore_info->reference_count > 0) &&
(IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
{
(void) FormatLocaleFile(stderr,"Warning: unexpected recursive lock!\n");
(void) fflush(stderr);
}
#endif
#if defined(MAGICKCORE_OPENMP_SUPPORT)
omp_set_lock((omp_lock_t *) &semaphore_info->mutex);
#elif defined(MAGICKCORE_THREAD_SUPPORT)
{
int
status;
status=pthread_mutex_lock(&semaphore_info->mutex);
if (status != 0)
{
errno=status;
perror("unable to lock mutex");
_exit(1);
}
}
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
EnterCriticalSection(&semaphore_info->mutex);
#endif
#if defined(MAGICKCORE_DEBUG)
semaphore_info->id=GetMagickThreadId();
semaphore_info->reference_count++;
#endif
}
MagickExport MagickBooleanType SemaphoreComponentGenesis(void)
{
InitializeMagickMutex();
return(MagickTrue);
}
MagickExport void SemaphoreComponentTerminus(void)
{
DestroyMagickMutex();
}
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
{
assert(semaphore_info != (SemaphoreInfo *) NULL);
assert(semaphore_info->signature == MagickSignature);
#if defined(MAGICKCORE_DEBUG)
assert(IsMagickThreadEqual(semaphore_info->id) != MagickFalse);
if (semaphore_info->reference_count == 0)
{
(void) FormatLocaleFile(stderr,
"Warning: semaphore lock already unlocked!\n");
(void) fflush(stderr);
return;
}
semaphore_info->reference_count--;
#endif
#if defined(MAGICKCORE_OPENMP_SUPPORT)
omp_unset_lock((omp_lock_t *) &semaphore_info->mutex);
#elif defined(MAGICKCORE_THREAD_SUPPORT)
{
int
status;
status=pthread_mutex_unlock(&semaphore_info->mutex);
if (status != 0)
{
errno=status;
perror("unable to unlock mutex");
_exit(1);
}
}
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
LeaveCriticalSection(&semaphore_info->mutex);
#endif
}