83#include "magick/studio.h"
84#include "magick/blob.h"
85#include "magick/blob-private.h"
86#include "magick/exception.h"
87#include "magick/exception-private.h"
88#include "magick/image-private.h"
89#include "magick/memory_.h"
90#include "magick/memory-private.h"
91#include "magick/policy.h"
92#include "magick/random_.h"
93#include "magick/resource_.h"
94#include "magick/semaphore.h"
95#include "magick/string_.h"
96#include "magick/string-private.h"
97#include "magick/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 virtual_anonymous_memory = 0;
206static void *MSCMalloc(
size_t size)
208 return(malloc(size));
211static void *MSCRealloc(
void* ptr,
size_t size)
213 return(realloc(ptr,size));
216static void MSCFree(
void* ptr)
222static MagickMemoryMethods
226 (AcquireMemoryHandler) MSCMalloc,
227 (ResizeMemoryHandler) MSCRealloc,
228 (DestroyMemoryHandler) MSCFree,
230 (AcquireMemoryHandler) malloc,
231 (ResizeMemoryHandler) realloc,
232 (DestroyMemoryHandler) free,
234 (AcquireAlignedMemoryHandler) NULL,
235 (RelinquishAlignedMemoryHandler) NULL
237#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
244static volatile DataSegmentInfo
245 *free_segments = (DataSegmentInfo *) NULL;
250static MagickBooleanType
279#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC)
280#define AcquireAlignedMemory_Actual AcquireAlignedMemory_STDC
281static inline void *AcquireAlignedMemory_STDC(
const size_t size)
284 extent = CACHE_ALIGNED(size);
291 return(aligned_alloc(CACHE_LINE_SIZE,extent));
293#elif defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
294#define AcquireAlignedMemory_Actual AcquireAlignedMemory_POSIX
295static inline void *AcquireAlignedMemory_POSIX(
const size_t size)
300 if (posix_memalign(&memory,CACHE_LINE_SIZE,size))
304#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
305#define AcquireAlignedMemory_Actual AcquireAlignedMemory_WinAPI
306static inline void *AcquireAlignedMemory_WinAPI(
const size_t size)
308 return(_aligned_malloc(size,CACHE_LINE_SIZE));
311#define ALIGNMENT_OVERHEAD \
312 (MAGICKCORE_MAX_ALIGNMENT_PADDING(CACHE_LINE_SIZE) + MAGICKCORE_SIZEOF_VOID_P)
313static inline void *reserve_space_for_actual_base_address(
void *
const p)
315 return((
void **) p+1);
318static inline void **pointer_to_space_for_actual_base_address(
void *
const p)
320 return((
void **) p-1);
323static inline void *actual_base_address(
void *
const p)
325 return(*pointer_to_space_for_actual_base_address(p));
328static inline void *align_to_cache(
void *
const p)
330 return((
void *) CACHE_ALIGNED((MagickAddressType) p));
333static inline void *adjust(
void *
const p)
335 return(align_to_cache(reserve_space_for_actual_base_address(p)));
338#define AcquireAlignedMemory_Actual AcquireAlignedMemory_Generic
339static inline void *AcquireAlignedMemory_Generic(
const size_t size)
348 #if SIZE_MAX < ALIGNMENT_OVERHEAD
349 #error "CACHE_LINE_SIZE is way too big."
351 extent=(size+ALIGNMENT_OVERHEAD);
357 p=AcquireMagickMemory(extent);
361 *pointer_to_space_for_actual_base_address(memory)=p;
366MagickExport
void *AcquireAlignedMemory(
const size_t count,
const size_t quantum)
371 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
372 (size > GetMaxMemoryRequest()))
377 if (memory_methods.acquire_aligned_memory_handler != (AcquireAlignedMemoryHandler) NULL)
378 return(memory_methods.acquire_aligned_memory_handler(size,CACHE_LINE_SIZE));
379 return(AcquireAlignedMemory_Actual(size));
382#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
407static inline size_t AllocationPolicy(
size_t size)
416 assert(size % (4*
sizeof(
size_t)) == 0);
417 if (size <= BlockThreshold)
418 return(size/(4*
sizeof(
size_t)));
422 if (size > (
size_t) (BlockThreshold*(1L << (MaxBlockExponent-1L))))
423 return(MaxBlocks-1L);
427 blocksize=BlockThreshold/(4*
sizeof(size_t));
428 for ( ; size > BlockThreshold; size/=2)
430 assert(blocksize > (BlockThreshold/(4*
sizeof(
size_t))));
431 assert(blocksize < (MaxBlocks-1L));
435static inline void InsertFreeBlock(
void *block,
const size_t i)
444 size=SizeOfBlock(block);
445 previous=(
void *) NULL;
446 next=memory_pool.blocks[i];
447 while ((next != (
void *) NULL) && (SizeOfBlock(next) < size))
450 next=NextBlockInList(next);
452 PreviousBlockInList(block)=previous;
453 NextBlockInList(block)=next;
454 if (previous != (
void *) NULL)
455 NextBlockInList(previous)=block;
457 memory_pool.blocks[i]=block;
458 if (next != (
void *) NULL)
459 PreviousBlockInList(next)=block;
462static inline void RemoveFreeBlock(
void *block,
const size_t i)
468 next=NextBlockInList(block);
469 previous=PreviousBlockInList(block);
470 if (previous == (
void *) NULL)
471 memory_pool.blocks[i]=next;
473 NextBlockInList(previous)=next;
474 if (next != (
void *) NULL)
475 PreviousBlockInList(next)=previous;
478static void *AcquireBlock(
size_t size)
489 size=(size_t) (size+
sizeof(
size_t)+6*
sizeof(
size_t)-1) & -(4U*
sizeof(size_t));
490 i=AllocationPolicy(size);
491 block=memory_pool.blocks[i];
492 while ((block != (
void *) NULL) && (SizeOfBlock(block) < size))
493 block=NextBlockInList(block);
494 if (block == (
void *) NULL)
497 while (memory_pool.blocks[i] == (
void *) NULL)
499 block=memory_pool.blocks[i];
501 return((
void *) NULL);
503 assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
504 assert(SizeOfBlock(block) >= size);
505 RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
506 if (SizeOfBlock(block) > size)
517 next=(
char *) block+size;
518 blocksize=SizeOfBlock(block)-size;
519 *BlockHeader(next)=blocksize;
520 *BlockFooter(next,blocksize)=blocksize;
521 InsertFreeBlock(next,AllocationPolicy(blocksize));
522 *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask);
524 assert(size == SizeOfBlock(block));
525 *BlockHeader(NextBlock(block))|=PreviousBlockBit;
526 memory_pool.allocation+=size;
554MagickExport
void *AcquireMagickMemory(
const size_t size)
559#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
560 memory=memory_methods.acquire_memory_handler(size == 0 ? 1UL : size);
563 ActivateSemaphoreInfo(&memory_semaphore);
564 if (free_segments == (DataSegmentInfo *) NULL)
566 LockSemaphoreInfo(memory_semaphore);
567 if (free_segments == (DataSegmentInfo *) NULL)
572 assert(2*
sizeof(
size_t) > (
size_t) (~SizeMask));
573 (void) memset(&memory_pool,0,
sizeof(memory_pool));
574 memory_pool.allocation=SegmentSize;
575 memory_pool.blocks[MaxBlocks]=(
void *) (-1);
576 for (i=0; i < MaxSegments; i++)
579 memory_pool.segment_pool[i].previous=
580 (&memory_pool.segment_pool[i-1]);
581 if (i != (MaxSegments-1))
582 memory_pool.segment_pool[i].next=(&memory_pool.segment_pool[i+1]);
584 free_segments=(&memory_pool.segment_pool[0]);
586 UnlockSemaphoreInfo(memory_semaphore);
588 LockSemaphoreInfo(memory_semaphore);
589 memory=AcquireBlock(size == 0 ? 1UL : size);
590 if (memory == (
void *) NULL)
592 if (ExpandHeap(size == 0 ? 1UL : size) != MagickFalse)
593 memory=AcquireBlock(size == 0 ? 1UL : size);
595 UnlockSemaphoreInfo(memory_semaphore);
628MagickExport
void *AcquireCriticalMemory(
const size_t size)
630#if !defined(STDERR_FILENO)
631#define STDERR_FILENO 2
637 static const char fatal_message[] =
638 "ImageMagick: fatal error: unable to acquire critical memory\n";
646 memory=AcquireMagickMemory(size);
647 if (memory != (
void *) NULL)
649 status=write(STDERR_FILENO,fatal_message,
sizeof(fatal_message)-1);
651 MagickCoreTerminus();
680MagickExport
void *AcquireQuantumMemory(
const size_t count,
const size_t quantum)
685 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
686 (size > GetMaxMemoryRequest()))
691 return(AcquireMagickMemory(size));
720MagickExport MemoryInfo *AcquireVirtualMemory(
const size_t count,
721 const size_t quantum)
732 if (HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse)
735 return((MemoryInfo *) NULL);
737 if (virtual_anonymous_memory == 0)
739 virtual_anonymous_memory=1;
740 value=GetPolicyValue(
"system:memory-map");
741 if (LocaleCompare(value,
"anonymous") == 0)
746#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
747 virtual_anonymous_memory=2;
750 value=DestroyString(value);
752 memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1,
753 sizeof(*memory_info)));
754 if (memory_info == (MemoryInfo *) NULL)
755 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
756 (void) memset(memory_info,0,
sizeof(*memory_info));
757 memory_info->length=size;
758 memory_info->signature=MagickCoreSignature;
759 if ((virtual_anonymous_memory == 1) && (size <= GetMaxMemoryRequest()))
761 memory_info->blob=AcquireAlignedMemory(1,size);
762 if (memory_info->blob != NULL)
763 memory_info->type=AlignedVirtualMemory;
765 if (memory_info->blob == NULL)
770 memory_info->blob=NULL;
771 if (size <= GetMaxMemoryRequest())
772 memory_info->blob=MapBlob(-1,IOMode,0,size);
773 if (memory_info->blob != NULL)
774 memory_info->type=MapVirtualMemory;
783 file=AcquireUniqueFileResource(memory_info->filename);
789 offset=(MagickOffsetType) lseek(file,size-1,SEEK_SET);
790 if ((offset == (MagickOffsetType) (size-1)) &&
791 (write(file,
"",1) == 1))
793#if !defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
794 memory_info->blob=MapBlob(file,IOMode,0,size);
796 if (posix_fallocate(file,0,(MagickOffsetType) size) == 0)
797 memory_info->blob=MapBlob(file,IOMode,0,size);
799 if (memory_info->blob != NULL)
800 memory_info->type=MapVirtualMemory;
803 (void) RelinquishUniqueFileResource(
804 memory_info->filename);
805 *memory_info->filename=
'\0';
812 if (memory_info->blob == NULL)
814 memory_info->blob=AcquireQuantumMemory(1,size);
815 if (memory_info->blob != NULL)
816 memory_info->type=UnalignedVirtualMemory;
818 if (memory_info->blob == NULL)
819 memory_info=RelinquishVirtualMemory(memory_info);
852MagickExport
void *CopyMagickMemory(
void *magick_restrict destination,
853 const void *magick_restrict source,
const size_t size)
861 assert(destination != (
void *) NULL);
862 assert(source != (
const void *) NULL);
863 p=(
const unsigned char *) source;
864 q=(
unsigned char *) destination;
865 if (((q+size) < p) || (q > (p+size)))
868 default:
return(memcpy(destination,source,size));
869 case 8: *q++=(*p++); magick_fallthrough;
870 case 7: *q++=(*p++); magick_fallthrough;
871 case 6: *q++=(*p++); magick_fallthrough;
872 case 5: *q++=(*p++); magick_fallthrough;
873 case 4: *q++=(*p++); magick_fallthrough;
874 case 3: *q++=(*p++); magick_fallthrough;
875 case 2: *q++=(*p++); magick_fallthrough;
876 case 1: *q++=(*p++); magick_fallthrough;
877 case 0:
return(destination);
879 return(memmove(destination,source,size));
900MagickExport
void DestroyMagickMemory(
void)
902#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
907 ActivateSemaphoreInfo(&memory_semaphore);
908 LockSemaphoreInfo(memory_semaphore);
909 for (i=0; i < (ssize_t) memory_pool.number_segments; i++)
910 if (memory_pool.segments[i]->mapped == MagickFalse)
911 memory_methods.destroy_memory_handler(
912 memory_pool.segments[i]->allocation);
914 (
void) UnmapBlob(memory_pool.segments[i]->allocation,
915 memory_pool.segments[i]->length);
916 free_segments=(DataSegmentInfo *) NULL;
917 (void) memset(&memory_pool,0,
sizeof(memory_pool));
918 UnlockSemaphoreInfo(memory_semaphore);
919 DestroySemaphoreInfo(&memory_semaphore);
923#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
947static MagickBooleanType ExpandHeap(
size_t size)
967 blocksize=((size+12*
sizeof(size_t))+SegmentSize-1) & -SegmentSize;
968 assert(memory_pool.number_segments < MaxSegments);
969 segment=MapBlob(-1,IOMode,0,blocksize);
970 mapped=segment != (
void *) NULL ? MagickTrue : MagickFalse;
971 if (segment == (
void *) NULL)
972 segment=(
void *) memory_methods.acquire_memory_handler(blocksize);
973 if (segment == (
void *) NULL)
975 segment_info=(DataSegmentInfo *) free_segments;
976 free_segments=segment_info->next;
977 segment_info->mapped=mapped;
978 segment_info->length=blocksize;
979 segment_info->allocation=segment;
980 segment_info->bound=(
char *) segment+blocksize;
981 i=(ssize_t) memory_pool.number_segments-1;
982 for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
983 memory_pool.segments[i+1]=memory_pool.segments[i];
984 memory_pool.segments[i+1]=segment_info;
985 memory_pool.number_segments++;
986 size=blocksize-12*
sizeof(size_t);
987 block=(
char *) segment_info->allocation+4*
sizeof(
size_t);
988 *BlockHeader(block)=size | PreviousBlockBit;
989 *BlockFooter(block,size)=size;
990 InsertFreeBlock(block,AllocationPolicy(size));
991 block=NextBlock(block);
992 assert(block < segment_info->bound);
993 *BlockHeader(block)=2*
sizeof(size_t);
994 *BlockHeader(NextBlock(block))=PreviousBlockBit;
1028MagickExport
void GetMagickMemoryMethods(
1029 AcquireMemoryHandler *acquire_memory_handler,
1030 ResizeMemoryHandler *resize_memory_handler,
1031 DestroyMemoryHandler *destroy_memory_handler)
1033 assert(acquire_memory_handler != (AcquireMemoryHandler *) NULL);
1034 assert(resize_memory_handler != (ResizeMemoryHandler *) NULL);
1035 assert(destroy_memory_handler != (DestroyMemoryHandler *) NULL);
1036 *acquire_memory_handler=memory_methods.acquire_memory_handler;
1037 *resize_memory_handler=memory_methods.resize_memory_handler;
1038 *destroy_memory_handler=memory_methods.destroy_memory_handler;
1059MagickExport
size_t GetMaxMemoryRequest(
void)
1061#define MinMemoryRequest "16MiB"
1063 if (max_memory_request == 0)
1068 max_memory_request=(size_t) MAGICK_SSIZE_MAX;
1069 value=GetPolicyValue(
"system:max-memory-request");
1070 if (value != (
char *) NULL)
1075 max_memory_request=MagickMax(StringToSizeType(value,100.0),
1076 StringToSizeType(MinMemoryRequest,100.0));
1077 value=DestroyString(value);
1080 return(MagickMin(max_memory_request,(
size_t) MAGICK_SSIZE_MAX));
1105MagickExport
void *GetVirtualMemoryBlob(
const MemoryInfo *memory_info)
1107 assert(memory_info != (
const MemoryInfo *) NULL);
1108 assert(memory_info->signature == MagickCoreSignature);
1109 return(memory_info->blob);
1135MagickExport
void *RelinquishAlignedMemory(
void *memory)
1137 if (memory == (
void *) NULL)
1138 return((
void *) NULL);
1139 if (memory_methods.relinquish_aligned_memory_handler != (RelinquishAlignedMemoryHandler) NULL)
1141 memory_methods.relinquish_aligned_memory_handler(memory);
1144#if defined(MAGICKCORE_HAVE_ALIGNED_MALLOC) || defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
1146#elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
1147 _aligned_free(memory);
1149 RelinquishMagickMemory(actual_base_address(memory));
1177MagickExport
void *RelinquishMagickMemory(
void *memory)
1179 if (memory == (
void *) NULL)
1180 return((
void *) NULL);
1181#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1182 memory_methods.destroy_memory_handler(memory);
1184 LockSemaphoreInfo(memory_semaphore);
1185 assert((SizeOfBlock(memory) % (4*
sizeof(
size_t))) == 0);
1186 assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
1187 if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
1195 previous=PreviousBlock(memory);
1196 RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
1197 *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
1198 (*BlockHeader(previous) & ~SizeMask);
1201 if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
1209 next=NextBlock(memory);
1210 RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
1211 *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
1212 (*BlockHeader(memory) & ~SizeMask);
1214 *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
1215 *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
1216 InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
1217 UnlockSemaphoreInfo(memory_semaphore);
1219 return((
void *) NULL);
1244MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info)
1246 assert(memory_info != (MemoryInfo *) NULL);
1247 assert(memory_info->signature == MagickCoreSignature);
1248 if (memory_info->blob != (
void *) NULL)
1249 switch (memory_info->type)
1251 case AlignedVirtualMemory:
1253 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1254 memory_info->blob=RelinquishAlignedMemory(memory_info->blob);
1257 case MapVirtualMemory:
1259 (void) UnmapBlob(memory_info->blob,memory_info->length);
1260 memory_info->blob=NULL;
1261 if (*memory_info->filename !=
'\0')
1262 (void) RelinquishUniqueFileResource(memory_info->filename);
1265 case UnalignedVirtualMemory:
1268 (void) ShredMagickMemory(memory_info->blob,memory_info->length);
1269 memory_info->blob=RelinquishMagickMemory(memory_info->blob);
1273 memory_info->signature=(~MagickCoreSignature);
1274 memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info);
1275 return(memory_info);
1308MagickExport
void *ResetMagickMemory(
void *memory,
int c,
const size_t size)
1310 volatile unsigned char
1311 *p = (
volatile unsigned char *) memory;
1316 assert(memory != (
void *) NULL);
1318 *p++=(
unsigned char) c;
1340MagickPrivate
void ResetMaxMemoryRequest(
void)
1342 max_memory_request=0;
1363MagickPrivate
void ResetVirtualAnonymousMemory(
void)
1365 virtual_anonymous_memory=0;
1395#if defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1396static inline void *ResizeBlock(
void *block,
size_t size)
1401 if (block == (
void *) NULL)
1402 return(AcquireBlock(size));
1403 memory=AcquireBlock(size);
1404 if (memory == (
void *) NULL)
1405 return((
void *) NULL);
1406 if (size <= (SizeOfBlock(block)-
sizeof(
size_t)))
1407 (void) memcpy(memory,block,size);
1409 (
void) memcpy(memory,block,SizeOfBlock(block)-
sizeof(
size_t));
1410 memory_pool.allocation+=size;
1415MagickExport
void *ResizeMagickMemory(
void *memory,
const size_t size)
1420 if (memory == (
void *) NULL)
1421 return(AcquireMagickMemory(size));
1422#if !defined(MAGICKCORE_ANONYMOUS_MEMORY_SUPPORT)
1423 block=memory_methods.resize_memory_handler(memory,size == 0 ? 1UL : size);
1424 if (block == (
void *) NULL)
1425 memory=RelinquishMagickMemory(memory);
1427 LockSemaphoreInfo(memory_semaphore);
1428 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1429 if (block == (
void *) NULL)
1431 if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1433 UnlockSemaphoreInfo(memory_semaphore);
1434 memory=RelinquishMagickMemory(memory);
1435 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1437 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1438 assert(block != (
void *) NULL);
1440 UnlockSemaphoreInfo(memory_semaphore);
1441 memory=RelinquishMagickMemory(memory);
1475MagickExport
void *ResizeQuantumMemory(
void *memory,
const size_t count,
1476 const size_t quantum)
1481 if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ||
1482 (size > GetMaxMemoryRequest()))
1485 memory=RelinquishMagickMemory(memory);
1488 if (size > GetMaxMemoryRequest())
1490 return(ResizeMagickMemory(memory,size));
1520MagickExport
void SetMagickAlignedMemoryMethods(
1521 AcquireAlignedMemoryHandler acquire_aligned_memory_handler,
1522 RelinquishAlignedMemoryHandler relinquish_aligned_memory_handler)
1524 memory_methods.acquire_aligned_memory_handler=acquire_aligned_memory_handler;
1525 memory_methods.relinquish_aligned_memory_handler=
1526 relinquish_aligned_memory_handler;
1559MagickExport
void SetMagickMemoryMethods(
1560 AcquireMemoryHandler acquire_memory_handler,
1561 ResizeMemoryHandler resize_memory_handler,
1562 DestroyMemoryHandler destroy_memory_handler)
1567 if (acquire_memory_handler != (AcquireMemoryHandler) NULL)
1568 memory_methods.acquire_memory_handler=acquire_memory_handler;
1569 if (resize_memory_handler != (ResizeMemoryHandler) NULL)
1570 memory_methods.resize_memory_handler=resize_memory_handler;
1571 if (destroy_memory_handler != (DestroyMemoryHandler) NULL)
1572 memory_methods.destroy_memory_handler=destroy_memory_handler;
1597MagickPrivate
void SetMaxMemoryRequest(
const MagickSizeType limit)
1599 max_memory_request=MagickMin(limit,GetMaxMemoryRequest());
1628MagickPrivate MagickBooleanType ShredMagickMemory(
void *memory,
1629 const size_t length)
1646 if ((memory == NULL) || (length == 0))
1647 return(MagickFalse);
1654 property=GetEnvironmentValue(
"MAGICK_SHRED_PASSES");
1655 if (property != (
char *) NULL)
1657 passes=(ssize_t) StringToInteger(property);
1658 property=DestroyString(property);
1660 property=GetPolicyValue(
"system:shred");
1661 if (property != (
char *) NULL)
1663 passes=(ssize_t) StringToInteger(property);
1664 property=DestroyString(property);
1672 quantum=(size_t) MagickMin(length,MagickMinBufferExtent);
1673 random_info=AcquireRandomInfo();
1674 key=GetRandomKey(random_info,quantum);
1675 for (i=0; i < passes; i++)
1681 *p = (
unsigned char *) memory;
1683 for (j=0; j < length; j+=quantum)
1686 SetRandomKey(random_info,quantum,GetStringInfoDatum(key));
1687 (void) memcpy(p,GetStringInfoDatum(key),(
size_t)
1688 MagickMin(quantum,length-j));
1689 p+=(ptrdiff_t) quantum;
1694 key=DestroyStringInfo(key);
1695 random_info=DestroyRandomInfo(random_info);
1696 return(i < passes ? MagickFalse : MagickTrue);