83#include "MagickCore/studio.h"
84#include "MagickCore/blob.h"
85#include "MagickCore/blob-private.h"
86#include "MagickCore/exception.h"
87#include "MagickCore/exception-private.h"
88#include "MagickCore/image-private.h"
89#include "MagickCore/memory_.h"
90#include "MagickCore/memory-private.h"
91#include "MagickCore/policy.h"
92#include "MagickCore/policy-private.h"
93#include "MagickCore/resource_.h"
94#include "MagickCore/semaphore.h"
95#include "MagickCore/string_.h"
96#include "MagickCore/string-private.h"
97#include "MagickCore/utility-private.h"
102#define BlockFooter(block,size) \
103 ((size_t *) ((char *) (block)+(size)-2*sizeof(size_t)))
104#define BlockHeader(block) ((size_t *) (block)-1)
105#define BlockThreshold 1024
106#define MaxBlockExponent 16
107#define MaxBlocks ((BlockThreshold/(4*sizeof(size_t)))+MaxBlockExponent+1)
108#define MaxSegments 1024
109#define NextBlock(block) ((char *) (block)+SizeOfBlock(block))
110#define NextBlockInList(block) (*(void **) (block))
111#define PreviousBlock(block) ((char *) (block)-(*((size_t *) (block)-2)))
112#define PreviousBlockBit 0x01
113#define PreviousBlockInList(block) (*((void **) (block)+1))
114#define SegmentSize (2*1024*1024)
115#define SizeMask (~0x01)
116#define SizeOfBlock(block) (*BlockHeader(block) & SizeMask)
123 UndefinedVirtualMemory,
124 AlignedVirtualMemory,
126 UnalignedVirtualMemory
149 acquire_memory_handler;
152 resize_memory_handler;
155 destroy_memory_handler;
157 AcquireAlignedMemoryHandler
158 acquire_aligned_memory_handler;
160 RelinquishAlignedMemoryHandler
161 relinquish_aligned_memory_handler;
162} MagickMemoryMethods;
167 filename[MagickPathExtent];
188 *blocks[MaxBlocks+1];
194 *segments[MaxSegments],
195 segment_pool[MaxSegments];
202 max_memory_request = 0,
203 max_profile_size = 0,
204 virtual_anonymous_memory = 0;
206static MagickMemoryMethods
209 (AcquireMemoryHandler) malloc,
210 (ResizeMemoryHandler) realloc,
211 (DestroyMemoryHandler) free,
212 (AcquireAlignedMemoryHandler) NULL,
213 (RelinquishAlignedMemoryHandler) NULL
215#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
222static volatile DataSegmentInfo
223 *free_segments = (DataSegmentInfo *) NULL;
228static MagickBooleanType
257#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC)
258#define AcquireAlignedMemory_Actual AcquireAlignedMemory_STDC
259static inline void *AcquireAlignedMemory_STDC(
const size_t size)
262 extent = CACHE_ALIGNED(size);
269 return(aligned_alloc(CACHE_LINE_SIZE,extent));
271#elif defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
272#define AcquireAlignedMemory_Actual AcquireAlignedMemory_POSIX
273static inline void *AcquireAlignedMemory_POSIX(
const size_t size)
278 if (posix_memalign(&memory,CACHE_LINE_SIZE,size))
282#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
283#define AcquireAlignedMemory_Actual AcquireAlignedMemory_WinAPI
284static inline void *AcquireAlignedMemory_WinAPI(
const size_t size)
286 return(_aligned_malloc(size,CACHE_LINE_SIZE));
289#define ALIGNMENT_OVERHEAD \
290 (MAGICKCORE_MAX_ALIGNMENT_PADDING(CACHE_LINE_SIZE) + MAGICKCORE_SIZEOF_VOID_P)
291static inline void *reserve_space_for_actual_base_address(
void *
const p)
293 return((
void **) p+1);
296static inline void **pointer_to_space_for_actual_base_address(
void *
const p)
298 return((
void **) p-1);
301static inline void *actual_base_address(
void *
const p)
303 return(*pointer_to_space_for_actual_base_address(p));
306static inline void *align_to_cache(
void *
const p)
308 return((
void *) CACHE_ALIGNED((MagickAddressType) p));
311static inline void *adjust(
void *
const p)
313 return(align_to_cache(reserve_space_for_actual_base_address(p)));
316#define AcquireAlignedMemory_Actual AcquireAlignedMemory_Generic
317static inline void *AcquireAlignedMemory_Generic(
const size_t size)
326 #if SIZE_MAX < ALIGNMENT_OVERHEAD
327 #error "CACHE_LINE_SIZE is way too big."
329 extent=(size+ALIGNMENT_OVERHEAD);
335 p=AcquireMagickMemory(extent);
339 *pointer_to_space_for_actual_base_address(memory)=p;
344MagickExport
void *AcquireAlignedMemory(
const size_t count,
const size_t quantum)
349 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
350 (size > GetMaxMemoryRequest()))
355 if (memory_methods.acquire_aligned_memory_handler != (AcquireAlignedMemoryHandler) NULL)
356 return(memory_methods.acquire_aligned_memory_handler(size,CACHE_LINE_SIZE));
357 return(AcquireAlignedMemory_Actual(size));
360#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
385static inline size_t AllocationPolicy(
size_t size)
394 assert(size % (4*
sizeof(
size_t)) == 0);
395 if (size <= BlockThreshold)
396 return(size/(4*
sizeof(
size_t)));
400 if (size > (
size_t) (BlockThreshold*(1L << (MaxBlockExponent-1L))))
401 return(MaxBlocks-1L);
405 blocksize=BlockThreshold/(4*
sizeof(size_t));
406 for ( ; size > BlockThreshold; size/=2)
408 assert(blocksize > (BlockThreshold/(4*
sizeof(
size_t))));
409 assert(blocksize < (MaxBlocks-1L));
413static inline void InsertFreeBlock(
void *block,
const size_t i)
422 size=SizeOfBlock(block);
423 previous=(
void *) NULL;
424 next=memory_pool.blocks[i];
425 while ((next != (
void *) NULL) && (SizeOfBlock(next) < size))
428 next=NextBlockInList(next);
430 PreviousBlockInList(block)=previous;
431 NextBlockInList(block)=next;
432 if (previous != (
void *) NULL)
433 NextBlockInList(previous)=block;
435 memory_pool.blocks[i]=block;
436 if (next != (
void *) NULL)
437 PreviousBlockInList(next)=block;
440static inline void RemoveFreeBlock(
void *block,
const size_t i)
446 next=NextBlockInList(block);
447 previous=PreviousBlockInList(block);
448 if (previous == (
void *) NULL)
449 memory_pool.blocks[i]=next;
451 NextBlockInList(previous)=next;
452 if (next != (
void *) NULL)
453 PreviousBlockInList(next)=previous;
456static void *AcquireBlock(
size_t size)
467 size=(size_t) (size+
sizeof(
size_t)+6*
sizeof(
size_t)-1) & -(4U*
sizeof(size_t));
468 i=AllocationPolicy(size);
469 block=memory_pool.blocks[i];
470 while ((block != (
void *) NULL) && (SizeOfBlock(block) < size))
471 block=NextBlockInList(block);
472 if (block == (
void *) NULL)
475 while (memory_pool.blocks[i] == (
void *) NULL)
477 block=memory_pool.blocks[i];
479 return((
void *) NULL);
481 assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
482 assert(SizeOfBlock(block) >= size);
483 RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
484 if (SizeOfBlock(block) > size)
495 next=(
char *) block+size;
496 blocksize=SizeOfBlock(block)-size;
497 *BlockHeader(next)=blocksize;
498 *BlockFooter(next,blocksize)=blocksize;
499 InsertFreeBlock(next,AllocationPolicy(blocksize));
500 *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask);
502 assert(size == SizeOfBlock(block));
503 *BlockHeader(NextBlock(block))|=PreviousBlockBit;
504 memory_pool.allocation+=size;
532MagickExport
void *AcquireMagickMemory(
const size_t size)
537#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
538 memory=memory_methods.acquire_memory_handler(size == 0 ? 1UL : size);
541 ActivateSemaphoreInfo(&memory_semaphore);
542 if (free_segments == (DataSegmentInfo *) NULL)
544 LockSemaphoreInfo(memory_semaphore);
545 if (free_segments == (DataSegmentInfo *) NULL)
550 assert(2*
sizeof(
size_t) > (
size_t) (~SizeMask));
551 (void) memset(&memory_pool,0,
sizeof(memory_pool));
552 memory_pool.allocation=SegmentSize;
553 memory_pool.blocks[MaxBlocks]=(
void *) (-1);
554 for (i=0; i < MaxSegments; i++)
557 memory_pool.segment_pool[i].previous=
558 (&memory_pool.segment_pool[i-1]);
559 if (i != (MaxSegments-1))
560 memory_pool.segment_pool[i].next=(&memory_pool.segment_pool[i+1]);
562 free_segments=(&memory_pool.segment_pool[0]);
564 UnlockSemaphoreInfo(memory_semaphore);
566 LockSemaphoreInfo(memory_semaphore);
567 memory=AcquireBlock(size == 0 ? 1UL : size);
568 if (memory == (
void *) NULL)
570 if (ExpandHeap(size == 0 ? 1UL : size) != MagickFalse)
571 memory=AcquireBlock(size == 0 ? 1UL : size);
573 UnlockSemaphoreInfo(memory_semaphore);
606MagickExport
void *AcquireCriticalMemory(
const size_t size)
608#if !defined(STDERR_FILENO)
609#define STDERR_FILENO 2
612 static const char fatal_message[] =
613 "ImageMagick: fatal error: unable to acquire critical memory\n";
621 memory=AcquireMagickMemory(size);
622 if (memory != (
void *) NULL)
624 (void) MagickWrite(STDERR_FILENO,fatal_message,
sizeof(fatal_message)-1);
625 MagickCoreTerminus();
654MagickExport
void *AcquireQuantumMemory(
const size_t count,
const size_t quantum)
659 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
660 (size > GetMaxMemoryRequest()))
665 return(AcquireMagickMemory(size));
694MagickExport MemoryInfo *AcquireVirtualMemory(
const size_t count,
695 const size_t quantum)
706 if (HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse)
709 return((MemoryInfo *) NULL);
711 if (virtual_anonymous_memory == 0)
713 virtual_anonymous_memory=1;
714 value=GetPolicyValue(
"system:memory-map");
715 if (LocaleCompare(value,
"anonymous") == 0)
720#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
721 virtual_anonymous_memory=2;
724 value=DestroyString(value);
726 memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1,
727 sizeof(*memory_info)));
728 if (memory_info == (MemoryInfo *) NULL)
729 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
730 (void) memset(memory_info,0,
sizeof(*memory_info));
731 memory_info->length=size;
732 memory_info->signature=MagickCoreSignature;
733 if ((virtual_anonymous_memory == 1) && (size <= GetMaxMemoryRequest()))
735 memory_info->blob=AcquireAlignedMemory(1,size);
736 if (memory_info->blob != NULL)
737 memory_info->type=AlignedVirtualMemory;
739 if (memory_info->blob == NULL)
744 memory_info->blob=NULL;
745 if (size <= GetMaxMemoryRequest())
746 memory_info->blob=MapBlob(-1,IOMode,0,size);
747 if (memory_info->blob != NULL)
748 memory_info->type=MapVirtualMemory;
757 file=AcquireUniqueFileResource(memory_info->filename);
763 offset=(MagickOffsetType) lseek(file,(off_t) (size-1),SEEK_SET);
764 if ((offset == (MagickOffsetType) (size-1)) &&
765 (write(file,
"",1) == 1))
767#if !defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
768 memory_info->blob=MapBlob(file,IOMode,0,size);
770 if (posix_fallocate(file,0,(MagickOffsetType) size) == 0)
771 memory_info->blob=MapBlob(file,IOMode,0,size);
773 if (memory_info->blob != NULL)
774 memory_info->type=MapVirtualMemory;
777 (void) RelinquishUniqueFileResource(
778 memory_info->filename);
779 *memory_info->filename=
'\0';
782 (void) close_utf8(file);
786 if (memory_info->blob == NULL)
788 memory_info->blob=AcquireQuantumMemory(1,size);
789 if (memory_info->blob != NULL)
790 memory_info->type=UnalignedVirtualMemory;
792 if (memory_info->blob == NULL)
793 memory_info=RelinquishVirtualMemory(memory_info);
826MagickExport
void *CopyMagickMemory(
void *magick_restrict destination,
827 const void *magick_restrict source,
const size_t size)
835 assert(destination != (
void *) NULL);
836 assert(source != (
const void *) NULL);
837 p=(
const unsigned char *) source;
838 q=(
unsigned char *) destination;
839 if (((q+size) < p) || (q > (p+size)))
842 default:
return(memcpy(destination,source,size));
843 case 8: *q++=(*p++); magick_fallthrough;
844 case 7: *q++=(*p++); magick_fallthrough;
845 case 6: *q++=(*p++); magick_fallthrough;
846 case 5: *q++=(*p++); magick_fallthrough;
847 case 4: *q++=(*p++); magick_fallthrough;
848 case 3: *q++=(*p++); magick_fallthrough;
849 case 2: *q++=(*p++); magick_fallthrough;
850 case 1: *q++=(*p++); magick_fallthrough;
851 case 0:
return(destination);
853 return(memmove(destination,source,size));
874MagickExport
void DestroyMagickMemory(
void)
876#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
881 ActivateSemaphoreInfo(&memory_semaphore);
882 LockSemaphoreInfo(memory_semaphore);
883 for (i=0; i < (ssize_t) memory_pool.number_segments; i++)
884 if (memory_pool.segments[i]->mapped == MagickFalse)
885 memory_methods.destroy_memory_handler(
886 memory_pool.segments[i]->allocation);
888 (
void) UnmapBlob(memory_pool.segments[i]->allocation,
889 memory_pool.segments[i]->length);
890 free_segments=(DataSegmentInfo *) NULL;
891 (void) memset(&memory_pool,0,
sizeof(memory_pool));
892 UnlockSemaphoreInfo(memory_semaphore);
893 RelinquishSemaphoreInfo(&memory_semaphore);
897#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
921static MagickBooleanType ExpandHeap(
size_t size)
941 blocksize=((size+12*
sizeof(size_t))+SegmentSize-1) & -SegmentSize;
942 assert(memory_pool.number_segments < MaxSegments);
943 segment=MapBlob(-1,IOMode,0,blocksize);
944 mapped=segment != (
void *) NULL ? MagickTrue : MagickFalse;
945 if (segment == (
void *) NULL)
946 segment=(
void *) memory_methods.acquire_memory_handler(blocksize);
947 if (segment == (
void *) NULL)
949 segment_info=(DataSegmentInfo *) free_segments;
950 free_segments=segment_info->next;
951 segment_info->mapped=mapped;
952 segment_info->length=blocksize;
953 segment_info->allocation=segment;
954 segment_info->bound=(
char *) segment+blocksize;
955 i=(ssize_t) memory_pool.number_segments-1;
956 for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
957 memory_pool.segments[i+1]=memory_pool.segments[i];
958 memory_pool.segments[i+1]=segment_info;
959 memory_pool.number_segments++;
960 size=blocksize-12*
sizeof(size_t);
961 block=(
char *) segment_info->allocation+4*
sizeof(
size_t);
962 *BlockHeader(block)=size | PreviousBlockBit;
963 *BlockFooter(block,size)=size;
964 InsertFreeBlock(block,AllocationPolicy(size));
965 block=NextBlock(block);
966 assert(block < segment_info->bound);
967 *BlockHeader(block)=2*
sizeof(size_t);
968 *BlockHeader(NextBlock(block))=PreviousBlockBit;
1002MagickExport
void GetMagickMemoryMethods(
1003 AcquireMemoryHandler *acquire_memory_handler,
1004 ResizeMemoryHandler *resize_memory_handler,
1005 DestroyMemoryHandler *destroy_memory_handler)
1007 assert(acquire_memory_handler != (AcquireMemoryHandler *) NULL);
1008 assert(resize_memory_handler != (ResizeMemoryHandler *) NULL);
1009 assert(destroy_memory_handler != (DestroyMemoryHandler *) NULL);
1010 *acquire_memory_handler=memory_methods.acquire_memory_handler;
1011 *resize_memory_handler=memory_methods.resize_memory_handler;
1012 *destroy_memory_handler=memory_methods.destroy_memory_handler;
1033static size_t GetMaxMemoryRequestFromPolicy(
void)
1035#define MinMemoryRequest "16MiB"
1041 max_memory = (size_t) MAGICK_SSIZE_MAX;
1043 value=GetPolicyValue(
"system:max-memory-request");
1044 if (value != (
char *) NULL)
1049 max_memory=MagickMax(StringToSizeType(value,100.0),StringToSizeType(
1050 MinMemoryRequest,100.0));
1051 value=DestroyString(value);
1053 return(MagickMin(max_memory,(
size_t) MAGICK_SSIZE_MAX));
1056MagickExport
size_t GetMaxMemoryRequest(
void)
1058 if (max_memory_request == 0)
1064 max_memory_request=(size_t) MAGICK_SSIZE_MAX;
1065 max_memory_request=GetMaxMemoryRequestFromPolicy();
1067 return(max_memory_request);
1088static size_t GetMaxProfileSizeFromPolicy(
void)
1094 max=(size_t) MAGICK_SSIZE_MAX;
1096 value=GetPolicyValue(
"system:max-profile-size");
1097 if (value != (
char *) NULL)
1102 max=StringToSizeType(value,100.0);
1103 value=DestroyString(value);
1105 return(MagickMin(max,(
size_t) MAGICK_SSIZE_MAX));
1108MagickExport
size_t GetMaxProfileSize(
void)
1110 if (max_profile_size == 0)
1111 max_profile_size=GetMaxProfileSizeFromPolicy();
1112 return(max_profile_size);
1137MagickExport
void *GetVirtualMemoryBlob(
const MemoryInfo *memory_info)
1139 assert(memory_info != (
const MemoryInfo *) NULL);
1140 assert(memory_info->signature == MagickCoreSignature);
1141 return(memory_info->blob);
1167MagickExport
void *RelinquishAlignedMemory(
void *memory)
1169 if (memory == (
void *) NULL)
1170 return((
void *) NULL);
1171 if (memory_methods.relinquish_aligned_memory_handler != (RelinquishAlignedMemoryHandler) NULL)
1173 memory_methods.relinquish_aligned_memory_handler(memory);
1176#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC) || defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
1178#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
1179 _aligned_free(memory);
1181 RelinquishMagickMemory(actual_base_address(memory));
1209MagickExport
void *RelinquishMagickMemory(
void *memory)
1211 if (memory == (
void *) NULL)
1212 return((
void *) NULL);
1213#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1214 memory_methods.destroy_memory_handler(memory);
1216 LockSemaphoreInfo(memory_semaphore);
1217 assert((SizeOfBlock(memory) % (4*
sizeof(
size_t))) == 0);
1218 assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
1219 if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
1227 previous=PreviousBlock(memory);
1228 RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
1229 *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
1230 (*BlockHeader(previous) & ~SizeMask);
1233 if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
1241 next=NextBlock(memory);
1242 RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
1243 *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
1244 (*BlockHeader(memory) & ~SizeMask);
1246 *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
1247 *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
1248 InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
1249 UnlockSemaphoreInfo(memory_semaphore);
1251 return((
void *) NULL);
1276MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info)
1278 assert(memory_info != (MemoryInfo *) NULL);
1279 assert(memory_info->signature == MagickCoreSignature);
1280 if (memory_info->blob != (
void *) NULL)
1281 switch (memory_info->type)
1283 case AlignedVirtualMemory:
1285 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1286 memory_info->blob=RelinquishAlignedMemory(memory_info->blob);
1289 case MapVirtualMemory:
1291 (void) UnmapBlob(memory_info->blob,memory_info->length);
1292 memory_info->blob=NULL;
1293 if (*memory_info->filename !=
'\0')
1294 (void) RelinquishUniqueFileResource(memory_info->filename);
1297 case UnalignedVirtualMemory:
1300 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1301 memory_info->blob=RelinquishMagickMemory(memory_info->blob);
1305 memory_info->signature=(~MagickCoreSignature);
1306 memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info);
1307 return(memory_info);
1339MagickExport
void *ResetMagickMemory(
void *memory,
int c,
const size_t size)
1341 volatile unsigned char
1342 *p = (
volatile unsigned char *) memory;
1347 assert(memory != (
void *) NULL);
1349 *p++=(
unsigned char) c;
1371MagickPrivate
void ResetVirtualAnonymousMemory(
void)
1373 virtual_anonymous_memory=0;
1403#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1404static inline void *ResizeBlock(
void *block,
size_t size)
1409 if (block == (
void *) NULL)
1410 return(AcquireBlock(size));
1411 memory=AcquireBlock(size);
1412 if (memory == (
void *) NULL)
1413 return((
void *) NULL);
1414 if (size <= (SizeOfBlock(block)-
sizeof(
size_t)))
1415 (void) memcpy(memory,block,size);
1417 (
void) memcpy(memory,block,SizeOfBlock(block)-
sizeof(
size_t));
1418 memory_pool.allocation+=size;
1423MagickExport
void *ResizeMagickMemory(
void *memory,
const size_t size)
1428 if (memory == (
void *) NULL)
1429 return(AcquireMagickMemory(size));
1430#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1431 block=memory_methods.resize_memory_handler(memory,size == 0 ? 1UL : size);
1432 if (block == (
void *) NULL)
1433 memory=RelinquishMagickMemory(memory);
1435 LockSemaphoreInfo(memory_semaphore);
1436 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1437 if (block == (
void *) NULL)
1439 if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1441 UnlockSemaphoreInfo(memory_semaphore);
1442 memory=RelinquishMagickMemory(memory);
1443 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1445 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1446 assert(block != (
void *) NULL);
1448 UnlockSemaphoreInfo(memory_semaphore);
1449 memory=RelinquishMagickMemory(memory);
1483MagickExport
void *ResizeQuantumMemory(
void *memory,
const size_t count,
1484 const size_t quantum)
1489 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
1490 (size > GetMaxMemoryRequest()))
1493 memory=RelinquishMagickMemory(memory);
1496 return(ResizeMagickMemory(memory,size));
1526MagickExport
void SetMagickAlignedMemoryMethods(
1527 AcquireAlignedMemoryHandler acquire_aligned_memory_handler,
1528 RelinquishAlignedMemoryHandler relinquish_aligned_memory_handler)
1530 memory_methods.acquire_aligned_memory_handler=acquire_aligned_memory_handler;
1531 memory_methods.relinquish_aligned_memory_handler=
1532 relinquish_aligned_memory_handler;
1565MagickExport
void SetMagickMemoryMethods(
1566 AcquireMemoryHandler acquire_memory_handler,
1567 ResizeMemoryHandler resize_memory_handler,
1568 DestroyMemoryHandler destroy_memory_handler)
1573 if (acquire_memory_handler != (AcquireMemoryHandler) NULL)
1574 memory_methods.acquire_memory_handler=acquire_memory_handler;
1575 if (resize_memory_handler != (ResizeMemoryHandler) NULL)
1576 memory_methods.resize_memory_handler=resize_memory_handler;
1577 if (destroy_memory_handler != (DestroyMemoryHandler) NULL)
1578 memory_methods.destroy_memory_handler=destroy_memory_handler;
1603MagickPrivate
void SetMaxMemoryRequest(
const MagickSizeType limit)
1605 max_memory_request=(size_t) MagickMin(limit,GetMaxMemoryRequestFromPolicy());
1630MagickPrivate
void SetMaxProfileSize(
const MagickSizeType limit)
1632 max_profile_size=(size_t) MagickMin(limit,GetMaxProfileSizeFromPolicy());
1661MagickPrivate MagickBooleanType ShredMagickMemory(
void *memory,
1662 const size_t length)
1679 if ((memory == NULL) || (length == 0))
1680 return(MagickFalse);
1682 passes=GetShredPasses();
1688 quantum=(size_t) MagickMin(length,MagickMinBufferExtent);
1689 random_info=AcquireRandomInfo();
1690 key=GetRandomKey(random_info,quantum);
1691 for (i=0; i < passes; i++)
1697 *p = (
unsigned char *) memory;
1699 for (j=0; j < length; j+=quantum)
1702 SetRandomKey(random_info,quantum,GetStringInfoDatum(key));
1703 (void) memcpy(p,GetStringInfoDatum(key),(
size_t)
1704 MagickMin(quantum,length-j));
1705 p+=(ptrdiff_t) quantum;
1710 key=DestroyStringInfo(key);
1711 random_info=DestroyRandomInfo(random_info);
1712 return(i < passes ? MagickFalse : MagickTrue);