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/resource_.h"
93#include "MagickCore/semaphore.h"
94#include "MagickCore/string_.h"
95#include "MagickCore/string-private.h"
96#include "MagickCore/utility-private.h"
101#define BlockFooter(block,size) \
102 ((size_t *) ((char *) (block)+(size)-2*sizeof(size_t)))
103#define BlockHeader(block) ((size_t *) (block)-1)
104#define BlockThreshold 1024
105#define MaxBlockExponent 16
106#define MaxBlocks ((BlockThreshold/(4*sizeof(size_t)))+MaxBlockExponent+1)
107#define MaxSegments 1024
108#define NextBlock(block) ((char *) (block)+SizeOfBlock(block))
109#define NextBlockInList(block) (*(void **) (block))
110#define PreviousBlock(block) ((char *) (block)-(*((size_t *) (block)-2)))
111#define PreviousBlockBit 0x01
112#define PreviousBlockInList(block) (*((void **) (block)+1))
113#define SegmentSize (2*1024*1024)
114#define SizeMask (~0x01)
115#define SizeOfBlock(block) (*BlockHeader(block) & SizeMask)
122 UndefinedVirtualMemory,
123 AlignedVirtualMemory,
125 UnalignedVirtualMemory
148 acquire_memory_handler;
151 resize_memory_handler;
154 destroy_memory_handler;
156 AcquireAlignedMemoryHandler
157 acquire_aligned_memory_handler;
159 RelinquishAlignedMemoryHandler
160 relinquish_aligned_memory_handler;
161} MagickMemoryMethods;
166 filename[MagickPathExtent];
187 *blocks[MaxBlocks+1];
193 *segments[MaxSegments],
194 segment_pool[MaxSegments];
201 max_memory_request = 0,
202 max_profile_size = 0,
203 virtual_anonymous_memory = 0;
205static MagickMemoryMethods
208 (AcquireMemoryHandler) malloc,
209 (ResizeMemoryHandler) realloc,
210 (DestroyMemoryHandler) free,
211 (AcquireAlignedMemoryHandler) NULL,
212 (RelinquishAlignedMemoryHandler) NULL
214#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
221static volatile DataSegmentInfo
222 *free_segments = (DataSegmentInfo *) NULL;
227static MagickBooleanType
256#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC)
257#define AcquireAlignedMemory_Actual AcquireAlignedMemory_STDC
258static inline void *AcquireAlignedMemory_STDC(
const size_t size)
261 extent = CACHE_ALIGNED(size);
268 return(aligned_alloc(CACHE_LINE_SIZE,extent));
270#elif defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
271#define AcquireAlignedMemory_Actual AcquireAlignedMemory_POSIX
272static inline void *AcquireAlignedMemory_POSIX(
const size_t size)
277 if (posix_memalign(&memory,CACHE_LINE_SIZE,size))
281#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
282#define AcquireAlignedMemory_Actual AcquireAlignedMemory_WinAPI
283static inline void *AcquireAlignedMemory_WinAPI(
const size_t size)
285 return(_aligned_malloc(size,CACHE_LINE_SIZE));
288#define ALIGNMENT_OVERHEAD \
289 (MAGICKCORE_MAX_ALIGNMENT_PADDING(CACHE_LINE_SIZE) + MAGICKCORE_SIZEOF_VOID_P)
290static inline void *reserve_space_for_actual_base_address(
void *
const p)
292 return((
void **) p+1);
295static inline void **pointer_to_space_for_actual_base_address(
void *
const p)
297 return((
void **) p-1);
300static inline void *actual_base_address(
void *
const p)
302 return(*pointer_to_space_for_actual_base_address(p));
305static inline void *align_to_cache(
void *
const p)
307 return((
void *) CACHE_ALIGNED((MagickAddressType) p));
310static inline void *adjust(
void *
const p)
312 return(align_to_cache(reserve_space_for_actual_base_address(p)));
315#define AcquireAlignedMemory_Actual AcquireAlignedMemory_Generic
316static inline void *AcquireAlignedMemory_Generic(
const size_t size)
325 #if SIZE_MAX < ALIGNMENT_OVERHEAD
326 #error "CACHE_LINE_SIZE is way too big."
328 extent=(size+ALIGNMENT_OVERHEAD);
334 p=AcquireMagickMemory(extent);
338 *pointer_to_space_for_actual_base_address(memory)=p;
343MagickExport
void *AcquireAlignedMemory(
const size_t count,
const size_t quantum)
348 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
349 (size > GetMaxMemoryRequest()))
354 if (memory_methods.acquire_aligned_memory_handler != (AcquireAlignedMemoryHandler) NULL)
355 return(memory_methods.acquire_aligned_memory_handler(size,CACHE_LINE_SIZE));
356 return(AcquireAlignedMemory_Actual(size));
359#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
384static inline size_t AllocationPolicy(
size_t size)
393 assert(size % (4*
sizeof(
size_t)) == 0);
394 if (size <= BlockThreshold)
395 return(size/(4*
sizeof(
size_t)));
399 if (size > (
size_t) (BlockThreshold*(1L << (MaxBlockExponent-1L))))
400 return(MaxBlocks-1L);
404 blocksize=BlockThreshold/(4*
sizeof(size_t));
405 for ( ; size > BlockThreshold; size/=2)
407 assert(blocksize > (BlockThreshold/(4*
sizeof(
size_t))));
408 assert(blocksize < (MaxBlocks-1L));
412static inline void InsertFreeBlock(
void *block,
const size_t i)
421 size=SizeOfBlock(block);
422 previous=(
void *) NULL;
423 next=memory_pool.blocks[i];
424 while ((next != (
void *) NULL) && (SizeOfBlock(next) < size))
427 next=NextBlockInList(next);
429 PreviousBlockInList(block)=previous;
430 NextBlockInList(block)=next;
431 if (previous != (
void *) NULL)
432 NextBlockInList(previous)=block;
434 memory_pool.blocks[i]=block;
435 if (next != (
void *) NULL)
436 PreviousBlockInList(next)=block;
439static inline void RemoveFreeBlock(
void *block,
const size_t i)
445 next=NextBlockInList(block);
446 previous=PreviousBlockInList(block);
447 if (previous == (
void *) NULL)
448 memory_pool.blocks[i]=next;
450 NextBlockInList(previous)=next;
451 if (next != (
void *) NULL)
452 PreviousBlockInList(next)=previous;
455static void *AcquireBlock(
size_t size)
466 size=(size_t) (size+
sizeof(
size_t)+6*
sizeof(
size_t)-1) & -(4U*
sizeof(size_t));
467 i=AllocationPolicy(size);
468 block=memory_pool.blocks[i];
469 while ((block != (
void *) NULL) && (SizeOfBlock(block) < size))
470 block=NextBlockInList(block);
471 if (block == (
void *) NULL)
474 while (memory_pool.blocks[i] == (
void *) NULL)
476 block=memory_pool.blocks[i];
478 return((
void *) NULL);
480 assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
481 assert(SizeOfBlock(block) >= size);
482 RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
483 if (SizeOfBlock(block) > size)
494 next=(
char *) block+size;
495 blocksize=SizeOfBlock(block)-size;
496 *BlockHeader(next)=blocksize;
497 *BlockFooter(next,blocksize)=blocksize;
498 InsertFreeBlock(next,AllocationPolicy(blocksize));
499 *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask);
501 assert(size == SizeOfBlock(block));
502 *BlockHeader(NextBlock(block))|=PreviousBlockBit;
503 memory_pool.allocation+=size;
531MagickExport
void *AcquireMagickMemory(
const size_t size)
536#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
537 memory=memory_methods.acquire_memory_handler(size == 0 ? 1UL : size);
540 ActivateSemaphoreInfo(&memory_semaphore);
541 if (free_segments == (DataSegmentInfo *) NULL)
543 LockSemaphoreInfo(memory_semaphore);
544 if (free_segments == (DataSegmentInfo *) NULL)
549 assert(2*
sizeof(
size_t) > (
size_t) (~SizeMask));
550 (void) memset(&memory_pool,0,
sizeof(memory_pool));
551 memory_pool.allocation=SegmentSize;
552 memory_pool.blocks[MaxBlocks]=(
void *) (-1);
553 for (i=0; i < MaxSegments; i++)
556 memory_pool.segment_pool[i].previous=
557 (&memory_pool.segment_pool[i-1]);
558 if (i != (MaxSegments-1))
559 memory_pool.segment_pool[i].next=(&memory_pool.segment_pool[i+1]);
561 free_segments=(&memory_pool.segment_pool[0]);
563 UnlockSemaphoreInfo(memory_semaphore);
565 LockSemaphoreInfo(memory_semaphore);
566 memory=AcquireBlock(size == 0 ? 1UL : size);
567 if (memory == (
void *) NULL)
569 if (ExpandHeap(size == 0 ? 1UL : size) != MagickFalse)
570 memory=AcquireBlock(size == 0 ? 1UL : size);
572 UnlockSemaphoreInfo(memory_semaphore);
605MagickExport
void *AcquireCriticalMemory(
const size_t size)
607#if !defined(STDERR_FILENO)
608#define STDERR_FILENO 2
611 static const char fatal_message[] =
612 "ImageMagick: fatal error: unable to acquire critical memory\n";
620 memory=AcquireMagickMemory(size);
621 if (memory != (
void *) NULL)
623 (void) MagickWrite(STDERR_FILENO,fatal_message,
sizeof(fatal_message)-1);
624 MagickCoreTerminus();
653MagickExport
void *AcquireQuantumMemory(
const size_t count,
const size_t quantum)
658 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
659 (size > GetMaxMemoryRequest()))
664 return(AcquireMagickMemory(size));
693MagickExport MemoryInfo *AcquireVirtualMemory(
const size_t count,
694 const size_t quantum)
705 if (HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse)
708 return((MemoryInfo *) NULL);
710 if (virtual_anonymous_memory == 0)
712 virtual_anonymous_memory=1;
713 value=GetPolicyValue(
"system:memory-map");
714 if (LocaleCompare(value,
"anonymous") == 0)
719#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
720 virtual_anonymous_memory=2;
723 value=DestroyString(value);
725 memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1,
726 sizeof(*memory_info)));
727 if (memory_info == (MemoryInfo *) NULL)
728 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
729 (void) memset(memory_info,0,
sizeof(*memory_info));
730 memory_info->length=size;
731 memory_info->signature=MagickCoreSignature;
732 if ((virtual_anonymous_memory == 1) && (size <= GetMaxMemoryRequest()))
734 memory_info->blob=AcquireAlignedMemory(1,size);
735 if (memory_info->blob != NULL)
736 memory_info->type=AlignedVirtualMemory;
738 if (memory_info->blob == NULL)
743 memory_info->blob=NULL;
744 if (size <= GetMaxMemoryRequest())
745 memory_info->blob=MapBlob(-1,IOMode,0,size);
746 if (memory_info->blob != NULL)
747 memory_info->type=MapVirtualMemory;
756 file=AcquireUniqueFileResource(memory_info->filename);
762 offset=(MagickOffsetType) lseek(file,(off_t) (size-1),SEEK_SET);
763 if ((offset == (MagickOffsetType) (size-1)) &&
764 (write(file,
"",1) == 1))
766#if !defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
767 memory_info->blob=MapBlob(file,IOMode,0,size);
769 if (posix_fallocate(file,0,(MagickOffsetType) size) == 0)
770 memory_info->blob=MapBlob(file,IOMode,0,size);
772 if (memory_info->blob != NULL)
773 memory_info->type=MapVirtualMemory;
776 (void) RelinquishUniqueFileResource(
777 memory_info->filename);
778 *memory_info->filename=
'\0';
781 (void) close_utf8(file);
785 if (memory_info->blob == NULL)
787 memory_info->blob=AcquireQuantumMemory(1,size);
788 if (memory_info->blob != NULL)
789 memory_info->type=UnalignedVirtualMemory;
791 if (memory_info->blob == NULL)
792 memory_info=RelinquishVirtualMemory(memory_info);
825MagickExport
void *CopyMagickMemory(
void *magick_restrict destination,
826 const void *magick_restrict source,
const size_t size)
834 assert(destination != (
void *) NULL);
835 assert(source != (
const void *) NULL);
836 p=(
const unsigned char *) source;
837 q=(
unsigned char *) destination;
838 if (((q+size) < p) || (q > (p+size)))
841 default:
return(memcpy(destination,source,size));
842 case 8: *q++=(*p++); magick_fallthrough;
843 case 7: *q++=(*p++); magick_fallthrough;
844 case 6: *q++=(*p++); magick_fallthrough;
845 case 5: *q++=(*p++); magick_fallthrough;
846 case 4: *q++=(*p++); magick_fallthrough;
847 case 3: *q++=(*p++); magick_fallthrough;
848 case 2: *q++=(*p++); magick_fallthrough;
849 case 1: *q++=(*p++); magick_fallthrough;
850 case 0:
return(destination);
852 return(memmove(destination,source,size));
873MagickExport
void DestroyMagickMemory(
void)
875#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
880 ActivateSemaphoreInfo(&memory_semaphore);
881 LockSemaphoreInfo(memory_semaphore);
882 for (i=0; i < (ssize_t) memory_pool.number_segments; i++)
883 if (memory_pool.segments[i]->mapped == MagickFalse)
884 memory_methods.destroy_memory_handler(
885 memory_pool.segments[i]->allocation);
887 (
void) UnmapBlob(memory_pool.segments[i]->allocation,
888 memory_pool.segments[i]->length);
889 free_segments=(DataSegmentInfo *) NULL;
890 (void) memset(&memory_pool,0,
sizeof(memory_pool));
891 UnlockSemaphoreInfo(memory_semaphore);
892 RelinquishSemaphoreInfo(&memory_semaphore);
896#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
920static MagickBooleanType ExpandHeap(
size_t size)
940 blocksize=((size+12*
sizeof(size_t))+SegmentSize-1) & -SegmentSize;
941 assert(memory_pool.number_segments < MaxSegments);
942 segment=MapBlob(-1,IOMode,0,blocksize);
943 mapped=segment != (
void *) NULL ? MagickTrue : MagickFalse;
944 if (segment == (
void *) NULL)
945 segment=(
void *) memory_methods.acquire_memory_handler(blocksize);
946 if (segment == (
void *) NULL)
948 segment_info=(DataSegmentInfo *) free_segments;
949 free_segments=segment_info->next;
950 segment_info->mapped=mapped;
951 segment_info->length=blocksize;
952 segment_info->allocation=segment;
953 segment_info->bound=(
char *) segment+blocksize;
954 i=(ssize_t) memory_pool.number_segments-1;
955 for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
956 memory_pool.segments[i+1]=memory_pool.segments[i];
957 memory_pool.segments[i+1]=segment_info;
958 memory_pool.number_segments++;
959 size=blocksize-12*
sizeof(size_t);
960 block=(
char *) segment_info->allocation+4*
sizeof(
size_t);
961 *BlockHeader(block)=size | PreviousBlockBit;
962 *BlockFooter(block,size)=size;
963 InsertFreeBlock(block,AllocationPolicy(size));
964 block=NextBlock(block);
965 assert(block < segment_info->bound);
966 *BlockHeader(block)=2*
sizeof(size_t);
967 *BlockHeader(NextBlock(block))=PreviousBlockBit;
1001MagickExport
void GetMagickMemoryMethods(
1002 AcquireMemoryHandler *acquire_memory_handler,
1003 ResizeMemoryHandler *resize_memory_handler,
1004 DestroyMemoryHandler *destroy_memory_handler)
1006 assert(acquire_memory_handler != (AcquireMemoryHandler *) NULL);
1007 assert(resize_memory_handler != (ResizeMemoryHandler *) NULL);
1008 assert(destroy_memory_handler != (DestroyMemoryHandler *) NULL);
1009 *acquire_memory_handler=memory_methods.acquire_memory_handler;
1010 *resize_memory_handler=memory_methods.resize_memory_handler;
1011 *destroy_memory_handler=memory_methods.destroy_memory_handler;
1032static size_t GetMaxMemoryRequestFromPolicy(
void)
1034#define MinMemoryRequest "16MiB"
1040 max_memory = (size_t) MAGICK_SSIZE_MAX;
1042 value=GetPolicyValue(
"system:max-memory-request");
1043 if (value != (
char *) NULL)
1048 max_memory=MagickMax(StringToSizeType(value,100.0),StringToSizeType(
1049 MinMemoryRequest,100.0));
1050 value=DestroyString(value);
1052 return(MagickMin(max_memory,(
size_t) MAGICK_SSIZE_MAX));
1055MagickExport
size_t GetMaxMemoryRequest(
void)
1057 if (max_memory_request == 0)
1063 max_memory_request=(size_t) MAGICK_SSIZE_MAX;
1064 max_memory_request=GetMaxMemoryRequestFromPolicy();
1066 return(max_memory_request);
1087static size_t GetMaxProfileSizeFromPolicy(
void)
1093 max=(size_t) MAGICK_SSIZE_MAX;
1095 value=GetPolicyValue(
"system:max-profile-size");
1096 if (value != (
char *) NULL)
1101 max=StringToSizeType(value,100.0);
1102 value=DestroyString(value);
1104 return(MagickMin(max,(
size_t) MAGICK_SSIZE_MAX));
1107MagickExport
size_t GetMaxProfileSize(
void)
1109 if (max_profile_size == 0)
1110 max_profile_size=GetMaxProfileSizeFromPolicy();
1111 return(max_profile_size);
1136MagickExport
void *GetVirtualMemoryBlob(
const MemoryInfo *memory_info)
1138 assert(memory_info != (
const MemoryInfo *) NULL);
1139 assert(memory_info->signature == MagickCoreSignature);
1140 return(memory_info->blob);
1166MagickExport
void *RelinquishAlignedMemory(
void *memory)
1168 if (memory == (
void *) NULL)
1169 return((
void *) NULL);
1170 if (memory_methods.relinquish_aligned_memory_handler != (RelinquishAlignedMemoryHandler) NULL)
1172 memory_methods.relinquish_aligned_memory_handler(memory);
1175#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC) || defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
1177#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
1178 _aligned_free(memory);
1180 RelinquishMagickMemory(actual_base_address(memory));
1208MagickExport
void *RelinquishMagickMemory(
void *memory)
1210 if (memory == (
void *) NULL)
1211 return((
void *) NULL);
1212#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1213 memory_methods.destroy_memory_handler(memory);
1215 LockSemaphoreInfo(memory_semaphore);
1216 assert((SizeOfBlock(memory) % (4*
sizeof(
size_t))) == 0);
1217 assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
1218 if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
1226 previous=PreviousBlock(memory);
1227 RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
1228 *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
1229 (*BlockHeader(previous) & ~SizeMask);
1232 if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
1240 next=NextBlock(memory);
1241 RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
1242 *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
1243 (*BlockHeader(memory) & ~SizeMask);
1245 *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
1246 *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
1247 InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
1248 UnlockSemaphoreInfo(memory_semaphore);
1250 return((
void *) NULL);
1275MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info)
1277 assert(memory_info != (MemoryInfo *) NULL);
1278 assert(memory_info->signature == MagickCoreSignature);
1279 if (memory_info->blob != (
void *) NULL)
1280 switch (memory_info->type)
1282 case AlignedVirtualMemory:
1284 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1285 memory_info->blob=RelinquishAlignedMemory(memory_info->blob);
1288 case MapVirtualMemory:
1290 (void) UnmapBlob(memory_info->blob,memory_info->length);
1291 memory_info->blob=NULL;
1292 if (*memory_info->filename !=
'\0')
1293 (void) RelinquishUniqueFileResource(memory_info->filename);
1296 case UnalignedVirtualMemory:
1299 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1300 memory_info->blob=RelinquishMagickMemory(memory_info->blob);
1304 memory_info->signature=(~MagickCoreSignature);
1305 memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info);
1306 return(memory_info);
1338MagickExport
void *ResetMagickMemory(
void *memory,
int c,
const size_t size)
1340 volatile unsigned char
1341 *p = (
volatile unsigned char *) memory;
1346 assert(memory != (
void *) NULL);
1348 *p++=(
unsigned char) c;
1370MagickPrivate
void ResetVirtualAnonymousMemory(
void)
1372 virtual_anonymous_memory=0;
1402#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1403static inline void *ResizeBlock(
void *block,
size_t size)
1408 if (block == (
void *) NULL)
1409 return(AcquireBlock(size));
1410 memory=AcquireBlock(size);
1411 if (memory == (
void *) NULL)
1412 return((
void *) NULL);
1413 if (size <= (SizeOfBlock(block)-
sizeof(
size_t)))
1414 (void) memcpy(memory,block,size);
1416 (
void) memcpy(memory,block,SizeOfBlock(block)-
sizeof(
size_t));
1417 memory_pool.allocation+=size;
1422MagickExport
void *ResizeMagickMemory(
void *memory,
const size_t size)
1427 if (memory == (
void *) NULL)
1428 return(AcquireMagickMemory(size));
1429#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1430 block=memory_methods.resize_memory_handler(memory,size == 0 ? 1UL : size);
1431 if (block == (
void *) NULL)
1432 memory=RelinquishMagickMemory(memory);
1434 LockSemaphoreInfo(memory_semaphore);
1435 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1436 if (block == (
void *) NULL)
1438 if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1440 UnlockSemaphoreInfo(memory_semaphore);
1441 memory=RelinquishMagickMemory(memory);
1442 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1444 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1445 assert(block != (
void *) NULL);
1447 UnlockSemaphoreInfo(memory_semaphore);
1448 memory=RelinquishMagickMemory(memory);
1482MagickExport
void *ResizeQuantumMemory(
void *memory,
const size_t count,
1483 const size_t quantum)
1488 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
1489 (size > GetMaxMemoryRequest()))
1492 memory=RelinquishMagickMemory(memory);
1495 return(ResizeMagickMemory(memory,size));
1525MagickExport
void SetMagickAlignedMemoryMethods(
1526 AcquireAlignedMemoryHandler acquire_aligned_memory_handler,
1527 RelinquishAlignedMemoryHandler relinquish_aligned_memory_handler)
1529 memory_methods.acquire_aligned_memory_handler=acquire_aligned_memory_handler;
1530 memory_methods.relinquish_aligned_memory_handler=
1531 relinquish_aligned_memory_handler;
1564MagickExport
void SetMagickMemoryMethods(
1565 AcquireMemoryHandler acquire_memory_handler,
1566 ResizeMemoryHandler resize_memory_handler,
1567 DestroyMemoryHandler destroy_memory_handler)
1572 if (acquire_memory_handler != (AcquireMemoryHandler) NULL)
1573 memory_methods.acquire_memory_handler=acquire_memory_handler;
1574 if (resize_memory_handler != (ResizeMemoryHandler) NULL)
1575 memory_methods.resize_memory_handler=resize_memory_handler;
1576 if (destroy_memory_handler != (DestroyMemoryHandler) NULL)
1577 memory_methods.destroy_memory_handler=destroy_memory_handler;
1602MagickPrivate
void SetMaxMemoryRequest(
const MagickSizeType limit)
1604 max_memory_request=(size_t) MagickMin(limit,GetMaxMemoryRequestFromPolicy());
1629MagickPrivate
void SetMaxProfileSize(
const MagickSizeType limit)
1631 max_profile_size=(size_t) MagickMin(limit,GetMaxProfileSizeFromPolicy());
1660MagickPrivate MagickBooleanType ShredMagickMemory(
void *memory,
1661 const size_t length)
1678 if ((memory == NULL) || (length == 0))
1679 return(MagickFalse);
1686 property=GetEnvironmentValue(
"MAGICK_SHRED_PASSES");
1687 if (property != (
char *) NULL)
1689 passes=(ssize_t) StringToInteger(property);
1690 property=DestroyString(property);
1692 property=GetPolicyValue(
"system:shred");
1693 if (property != (
char *) NULL)
1695 passes=(ssize_t) StringToInteger(property);
1696 property=DestroyString(property);
1704 quantum=(size_t) MagickMin(length,MagickMinBufferExtent);
1705 random_info=AcquireRandomInfo();
1706 key=GetRandomKey(random_info,quantum);
1707 for (i=0; i < passes; i++)
1713 *p = (
unsigned char *) memory;
1715 for (j=0; j < length; j+=quantum)
1718 SetRandomKey(random_info,quantum,GetStringInfoDatum(key));
1719 (void) memcpy(p,GetStringInfoDatum(key),(
size_t)
1720 MagickMin(quantum,length-j));
1721 p+=(ptrdiff_t) quantum;
1726 key=DestroyStringInfo(key);
1727 random_info=DestroyRandomInfo(random_info);
1728 return(i < passes ? MagickFalse : MagickTrue);