2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % M M EEEEE M M OOO RRRR Y Y %
7 % MM MM E MM MM O O R R Y Y %
8 % M M M EEE M M M O O RRRR Y %
9 % M M E M M O O R R Y %
10 % M M EEEEE M M OOO R R Y %
13 % MagickCore Memory Allocation Methods %
20 % Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 % Segregate our memory requirements from any program that calls our API. This
37 % should help reduce the risk of others changing our program state or causing
40 % Our custom memory allocation manager implements a best-fit allocation policy
41 % using segregated free lists. It uses a linear distribution of size classes
42 % for lower sizes and a power of two distribution of size classes at higher
43 % sizes. It is based on the paper, "Fast Memory Allocation using Lazy Fits."
44 % written by Yoo C. Chung.
46 % By default, ANSI memory methods are called (e.g. malloc). Use the
47 % custom memory allocator by defining MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
48 % to allocate memory with private anonymous mapping rather than from the
56 #include "MagickCore/studio.h"
57 #include "MagickCore/blob.h"
58 #include "MagickCore/blob-private.h"
59 #include "MagickCore/exception.h"
60 #include "MagickCore/exception-private.h"
61 #include "MagickCore/memory_.h"
62 #include "MagickCore/memory-private.h"
63 #include "MagickCore/semaphore.h"
64 #include "MagickCore/string_.h"
69 #define BlockFooter(block,size) \
70 ((size_t *) ((char *) (block)+(size)-2*sizeof(size_t)))
71 #define BlockHeader(block) ((size_t *) (block)-1)
72 #define BlockSize 4096
73 #define BlockThreshold 1024
74 #define MaxBlockExponent 16
75 #define MaxBlocks ((BlockThreshold/(4*sizeof(size_t)))+MaxBlockExponent+1)
76 #define MaxSegments 1024
77 #define MemoryGuard ((0xdeadbeef << 31)+0xdeafdeed)
78 #define NextBlock(block) ((char *) (block)+SizeOfBlock(block))
79 #define NextBlockInList(block) (*(void **) (block))
80 #define PreviousBlock(block) ((char *) (block)-(*((size_t *) (block)-2)))
81 #define PreviousBlockBit 0x01
82 #define PreviousBlockInList(block) (*((void **) (block)+1))
83 #define SegmentSize (2*1024*1024)
84 #define SizeMask (~0x01)
85 #define SizeOfBlock(block) (*BlockHeader(block) & SizeMask)
90 typedef struct _DataSegmentInfo
102 struct _DataSegmentInfo
107 typedef struct _MagickMemoryMethods
110 acquire_memory_handler;
113 resize_memory_handler;
116 destroy_memory_handler;
117 } MagickMemoryMethods;
119 typedef struct _MemoryInfo
122 filename[MaxTextExtent];
131 typedef struct _MemoryPool
137 *blocks[MaxBlocks+1];
143 *segments[MaxSegments],
144 segment_pool[MaxSegments];
150 static MagickMemoryMethods
153 (AcquireMemoryHandler) malloc,
154 (ResizeMemoryHandler) realloc,
155 (DestroyMemoryHandler) free
158 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
163 *memory_semaphore = (SemaphoreInfo *) NULL;
165 static volatile DataSegmentInfo
166 *free_segments = (DataSegmentInfo *) NULL;
169 Forward declarations.
171 static MagickBooleanType
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 % A c q u i r e A l i g n e d M e m o r y %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 % AcquireAlignedMemory() returns a pointer to a block of memory at least size
187 % bytes whose address is a multiple of 16*sizeof(void *).
189 % The format of the AcquireAlignedMemory method is:
191 % void *AcquireAlignedMemory(const size_t count,const size_t quantum)
193 % A description of each parameter follows:
195 % o count: the number of quantum elements to allocate.
197 % o quantum: the number of bytes in each quantum.
200 MagickExport void *AcquireAlignedMemory(const size_t count,const size_t quantum)
202 #define AlignedExtent(size,alignment) \
203 (((size)+((alignment)-1)) & ~((alignment)-1))
214 if ((count == 0) || (quantum != (size/count)))
217 return((void *) NULL);
220 alignment=CACHE_LINE_SIZE;
221 extent=AlignedExtent(size,alignment);
222 if ((size == 0) || (alignment < sizeof(void *)) || (extent < size))
223 return((void *) NULL);
224 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
225 if (posix_memalign(&memory,alignment,extent) != 0)
227 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
228 memory=_aligned_malloc(extent,alignment);
234 extent=(size+alignment-1)+sizeof(void *);
240 memory=(void *) AlignedExtent((size_t) p+sizeof(void *),alignment);
241 *((void **) memory-1)=p;
249 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 + A c q u i r e B l o c k %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 % AcquireBlock() returns a pointer to a block of memory at least size bytes
262 % suitably aligned for any use.
264 % The format of the AcquireBlock method is:
266 % void *AcquireBlock(const size_t size)
268 % A description of each parameter follows:
270 % o size: the size of the memory in bytes to allocate.
274 static inline size_t AllocationPolicy(size_t size)
280 The linear distribution.
283 assert(size % (4*sizeof(size_t)) == 0);
284 if (size <= BlockThreshold)
285 return(size/(4*sizeof(size_t)));
287 Check for the largest block size.
289 if (size > (size_t) (BlockThreshold*(1L << (MaxBlockExponent-1L))))
290 return(MaxBlocks-1L);
292 Otherwise use a power of two distribution.
294 blocksize=BlockThreshold/(4*sizeof(size_t));
295 for ( ; size > BlockThreshold; size/=2)
297 assert(blocksize > (BlockThreshold/(4*sizeof(size_t))));
298 assert(blocksize < (MaxBlocks-1L));
302 static inline void InsertFreeBlock(void *block,const size_t i)
311 size=SizeOfBlock(block);
312 previous=(void *) NULL;
313 next=memory_pool.blocks[i];
314 while ((next != (void *) NULL) && (SizeOfBlock(next) < size))
317 next=NextBlockInList(next);
319 PreviousBlockInList(block)=previous;
320 NextBlockInList(block)=next;
321 if (previous != (void *) NULL)
322 NextBlockInList(previous)=block;
324 memory_pool.blocks[i]=block;
325 if (next != (void *) NULL)
326 PreviousBlockInList(next)=block;
329 static inline void RemoveFreeBlock(void *block,const size_t i)
335 next=NextBlockInList(block);
336 previous=PreviousBlockInList(block);
337 if (previous == (void *) NULL)
338 memory_pool.blocks[i]=next;
340 NextBlockInList(previous)=next;
341 if (next != (void *) NULL)
342 PreviousBlockInList(next)=previous;
345 static void *AcquireBlock(size_t size)
356 size=(size_t) (size+sizeof(size_t)+6*sizeof(size_t)-1) & -(4U*sizeof(size_t));
357 i=AllocationPolicy(size);
358 block=memory_pool.blocks[i];
359 while ((block != (void *) NULL) && (SizeOfBlock(block) < size))
360 block=NextBlockInList(block);
361 if (block == (void *) NULL)
364 while (memory_pool.blocks[i] == (void *) NULL)
366 block=memory_pool.blocks[i];
368 return((void *) NULL);
370 assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
371 assert(SizeOfBlock(block) >= size);
372 RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
373 if (SizeOfBlock(block) > size)
384 next=(char *) block+size;
385 blocksize=SizeOfBlock(block)-size;
386 *BlockHeader(next)=blocksize;
387 *BlockFooter(next,blocksize)=blocksize;
388 InsertFreeBlock(next,AllocationPolicy(blocksize));
389 *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask);
391 assert(size == SizeOfBlock(block));
392 *BlockHeader(NextBlock(block))|=PreviousBlockBit;
393 memory_pool.allocation+=size;
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % A c q u i r e M a g i c k M e m o r y %
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 % AcquireMagickMemory() returns a pointer to a block of memory at least size
410 % bytes suitably aligned for any use.
412 % The format of the AcquireMagickMemory method is:
414 % void *AcquireMagickMemory(const size_t size)
416 % A description of each parameter follows:
418 % o size: the size of the memory in bytes to allocate.
421 MagickExport void *AcquireMagickMemory(const size_t size)
426 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
427 memory=memory_methods.acquire_memory_handler(size == 0 ? 1UL : size);
429 if (memory_semaphore == (SemaphoreInfo *) NULL)
430 AcquireSemaphoreInfo(&memory_semaphore);
431 if (free_segments == (DataSegmentInfo *) NULL)
433 LockSemaphoreInfo(memory_semaphore);
434 if (free_segments == (DataSegmentInfo *) NULL)
439 assert(2*sizeof(size_t) > (size_t) (~SizeMask));
440 (void) ResetMagickMemory(&memory_pool,0,sizeof(memory_pool));
441 memory_pool.allocation=SegmentSize;
442 memory_pool.blocks[MaxBlocks]=(void *) (-1);
443 for (i=0; i < MaxSegments; i++)
446 memory_pool.segment_pool[i].previous=
447 (&memory_pool.segment_pool[i-1]);
448 if (i != (MaxSegments-1))
449 memory_pool.segment_pool[i].next=(&memory_pool.segment_pool[i+1]);
451 free_segments=(&memory_pool.segment_pool[0]);
453 UnlockSemaphoreInfo(memory_semaphore);
455 LockSemaphoreInfo(memory_semaphore);
456 memory=AcquireBlock(size == 0 ? 1UL : size);
457 if (memory == (void *) NULL)
459 if (ExpandHeap(size == 0 ? 1UL : size) != MagickFalse)
460 memory=AcquireBlock(size == 0 ? 1UL : size);
462 UnlockSemaphoreInfo(memory_semaphore);
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472 % A c q u i r e M e m o r y I n f o %
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478 % AcquireMemoryInfo() returns a pointer to a block of memory at least size
479 % bytes suitably aligned for any use.
481 % The format of the AcquireMemoryInfo method is:
483 % MagickInfo *AcquireMemoryInfo(const size_t size)
485 % A description of each parameter follows:
487 % o size: the size of the virtual memory in bytes to allocate.
490 MagickExport MemoryInfo *AcquireMemoryInfo(const size_t size)
492 return((MemoryInfo *) NULL);
496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500 % A c q u i r e Q u a n t u m M e m o r y %
504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 % AcquireQuantumMemory() returns a pointer to a block of memory at least
507 % count * quantum bytes suitably aligned for any use.
509 % The format of the AcquireQuantumMemory method is:
511 % void *AcquireQuantumMemory(const size_t count,const size_t quantum)
513 % A description of each parameter follows:
515 % o count: the number of quantum elements to allocate.
517 % o quantum: the number of bytes in each quantum.
520 MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
526 if ((count == 0) || (quantum != (size/count)))
529 return((void *) NULL);
531 return(AcquireMagickMemory(size));
535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539 % C o p y M a g i c k M e m o r y %
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 % CopyMagickMemory() copies size bytes from memory area source to the
546 % destination. Copying between objects that overlap will take place
547 % correctly. It returns destination.
549 % The format of the CopyMagickMemory method is:
551 % void *CopyMagickMemory(void *destination,const void *source,
554 % A description of each parameter follows:
556 % o destination: the destination.
558 % o source: the source.
560 % o size: the size of the memory in bytes to allocate.
563 MagickExport void *CopyMagickMemory(void *destination,const void *source,
566 register const unsigned char
569 register unsigned char
572 assert(destination != (void *) NULL);
573 assert(source != (const void *) NULL);
574 p=(const unsigned char *) source;
575 q=(unsigned char *) destination;
576 if (((q+size) < p) || (q > (p+size)))
579 default: return(memcpy(destination,source,size));
588 case 0: return(destination);
590 return(memmove(destination,source,size));
594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
598 + D e s t r o y M a g i c k M e m o r y %
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 % DestroyMagickMemory() deallocates memory associated with the memory manager.
606 % The format of the DestroyMagickMemory method is:
608 % DestroyMagickMemory(void)
611 MagickExport void DestroyMagickMemory(void)
613 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
617 if (memory_semaphore == (SemaphoreInfo *) NULL)
618 AcquireSemaphoreInfo(&memory_semaphore);
619 LockSemaphoreInfo(memory_semaphore);
620 UnlockSemaphoreInfo(memory_semaphore);
621 for (i=0; i < (ssize_t) memory_pool.number_segments; i++)
622 if (memory_pool.segments[i]->mapped == MagickFalse)
623 memory_methods.destroy_memory_handler(
624 memory_pool.segments[i]->allocation);
626 (void) UnmapBlob(memory_pool.segments[i]->allocation,
627 memory_pool.segments[i]->length);
628 free_segments=(DataSegmentInfo *) NULL;
629 (void) ResetMagickMemory(&memory_pool,0,sizeof(memory_pool));
630 DestroySemaphoreInfo(&memory_semaphore);
634 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 + E x p a n d H e a p %
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646 % ExpandHeap() get more memory from the system. It returns MagickTrue on
647 % success otherwise MagickFalse.
649 % The format of the ExpandHeap method is:
651 % MagickBooleanType ExpandHeap(size_t size)
653 % A description of each parameter follows:
655 % o size: the size of the memory in bytes we require.
658 static MagickBooleanType ExpandHeap(size_t size)
678 blocksize=((size+12*sizeof(size_t))+SegmentSize-1) & -SegmentSize;
679 assert(memory_pool.number_segments < MaxSegments);
680 segment=MapBlob(-1,IOMode,0,blocksize);
681 mapped=segment != (void *) NULL ? MagickTrue : MagickFalse;
682 if (segment == (void *) NULL)
683 segment=(void *) memory_methods.acquire_memory_handler(blocksize);
684 if (segment == (void *) NULL)
686 segment_info=(DataSegmentInfo *) free_segments;
687 free_segments=segment_info->next;
688 segment_info->mapped=mapped;
689 segment_info->length=blocksize;
690 segment_info->allocation=segment;
691 segment_info->bound=(char *) segment+blocksize;
692 i=(ssize_t) memory_pool.number_segments-1;
693 for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
694 memory_pool.segments[i+1]=memory_pool.segments[i];
695 memory_pool.segments[i+1]=segment_info;
696 memory_pool.number_segments++;
697 size=blocksize-12*sizeof(size_t);
698 block=(char *) segment_info->allocation+4*sizeof(size_t);
699 *BlockHeader(block)=size | PreviousBlockBit;
700 *BlockFooter(block,size)=size;
701 InsertFreeBlock(block,AllocationPolicy(size));
702 block=NextBlock(block);
703 assert(block < segment_info->bound);
704 *BlockHeader(block)=2*sizeof(size_t);
705 *BlockHeader(NextBlock(block))=PreviousBlockBit;
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 % G e t M a g i c k M e m o r y M e t h o d s %
719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721 % GetMagickMemoryMethods() gets the methods to acquire, resize, and destroy
724 % The format of the GetMagickMemoryMethods() method is:
726 % void GetMagickMemoryMethods(AcquireMemoryHandler *acquire_memory_handler,
727 % ResizeMemoryHandler *resize_memory_handler,
728 % DestroyMemoryHandler *destroy_memory_handler)
730 % A description of each parameter follows:
732 % o acquire_memory_handler: method to acquire memory (e.g. malloc).
734 % o resize_memory_handler: method to resize memory (e.g. realloc).
736 % o destroy_memory_handler: method to destroy memory (e.g. free).
739 MagickExport void GetMagickMemoryMethods(
740 AcquireMemoryHandler *acquire_memory_handler,
741 ResizeMemoryHandler *resize_memory_handler,
742 DestroyMemoryHandler *destroy_memory_handler)
744 assert(acquire_memory_handler != (AcquireMemoryHandler *) NULL);
745 assert(resize_memory_handler != (ResizeMemoryHandler *) NULL);
746 assert(destroy_memory_handler != (DestroyMemoryHandler *) NULL);
747 *acquire_memory_handler=memory_methods.acquire_memory_handler;
748 *resize_memory_handler=memory_methods.resize_memory_handler;
749 *destroy_memory_handler=memory_methods.destroy_memory_handler;
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757 % G e t M e m o r y I n f o M e m o r y %
761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763 % GetMemoryInfoMemory() returns a pointer to the allocated memory.
765 % The format of the GetMemoryInfoMemory method is:
767 % void *GetMemoryInfoMemory(const MemoryInfo *memory_info)
769 % A description of each parameter follows:
771 % o memory: A pointer to a block of memory to free for reuse.
774 MagickExport void *GetMemoryInfoMemory(const MemoryInfo *memory_info)
776 assert(memory_info != (const MemoryInfo *) NULL);
777 return(memory_info->memory);
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
785 % R e l i n q u i s h A l i g n e d M e m o r y %
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 % RelinquishAlignedMemory() frees memory acquired with AcquireAlignedMemory()
794 % The format of the RelinquishAlignedMemory method is:
796 % void *RelinquishAlignedMemory(void *memory)
798 % A description of each parameter follows:
800 % o memory: A pointer to a block of memory to free for reuse.
803 MagickExport void *RelinquishAlignedMemory(void *memory)
805 if (memory == (void *) NULL)
806 return((void *) NULL);
807 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
809 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
810 _aligned_free(memory);
812 free(*((void **) memory-1));
818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 % R e l i n q u i s h M a g i c k M e m o r y %
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 % RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
829 % or AcquireQuantumMemory() for reuse.
831 % The format of the RelinquishMagickMemory method is:
833 % void *RelinquishMagickMemory(void *memory)
835 % A description of each parameter follows:
837 % o memory: A pointer to a block of memory to free for reuse.
840 MagickExport void *RelinquishMagickMemory(void *memory)
842 if (memory == (void *) NULL)
843 return((void *) NULL);
844 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
845 memory_methods.destroy_memory_handler(memory);
847 LockSemaphoreInfo(memory_semaphore);
848 assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
849 assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
850 if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
856 Coalesce with previous adjacent block.
858 previous=PreviousBlock(memory);
859 RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
860 *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
861 (*BlockHeader(previous) & ~SizeMask);
864 if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
870 Coalesce with next adjacent block.
872 next=NextBlock(memory);
873 RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
874 *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
875 (*BlockHeader(memory) & ~SizeMask);
877 *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
878 *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
879 InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
880 UnlockSemaphoreInfo(memory_semaphore);
882 return((void *) NULL);
886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890 % R e l i n q u i s h V i r t u a l M e m o r y %
894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896 % RelinquishMemoryInfo() frees memory acquired with AcquireMemoryInfo()
899 % The format of the RelinquishMemoryInfo method is:
901 % void *RelinquishMemoryInfo(const MemoryInfo *memory_info)
903 % A description of each parameter follows:
905 % o memory_info: A pointer to a block of memory to free for reuse.
908 MagickExport MemoryInfo *RelinquishMemoryInfo(const MemoryInfo *memory_info)
910 return((MemoryInfo *) NULL);
914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
918 % R e s e t M a g i c k M e m o r y %
922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 % ResetMagickMemory() fills the first size bytes of the memory area pointed to
925 % by memory with the constant byte c.
927 % The format of the ResetMagickMemory method is:
929 % void *ResetMagickMemory(void *memory,int byte,const size_t size)
931 % A description of each parameter follows:
933 % o memory: a pointer to a memory allocation.
935 % o byte: set the memory to this value.
937 % o size: size of the memory to reset.
940 MagickExport void *ResetMagickMemory(void *memory,int byte,const size_t size)
942 assert(memory != (void *) NULL);
943 return(memset(memory,byte,size));
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % R e s i z e M a g i c k M e m o r y %
955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 % ResizeMagickMemory() changes the size of the memory and returns a pointer to
958 % the (possibly moved) block. The contents will be unchanged up to the
959 % lesser of the new and old sizes.
961 % The format of the ResizeMagickMemory method is:
963 % void *ResizeMagickMemory(void *memory,const size_t size)
965 % A description of each parameter follows:
967 % o memory: A pointer to a memory allocation.
969 % o size: the new size of the allocated memory.
973 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
974 static inline void *ResizeBlock(void *block,size_t size)
979 if (block == (void *) NULL)
980 return(AcquireBlock(size));
981 memory=AcquireBlock(size);
982 if (memory == (void *) NULL)
983 return((void *) NULL);
984 if (size <= (SizeOfBlock(block)-sizeof(size_t)))
985 (void) memcpy(memory,block,size);
987 (void) memcpy(memory,block,SizeOfBlock(block)-sizeof(size_t));
988 memory_pool.allocation+=size;
993 MagickExport void *ResizeMagickMemory(void *memory,const size_t size)
998 if (memory == (void *) NULL)
999 return(AcquireMagickMemory(size));
1000 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
1001 block=memory_methods.resize_memory_handler(memory,size == 0 ? 1UL : size);
1002 if (block == (void *) NULL)
1003 memory=RelinquishMagickMemory(memory);
1005 LockSemaphoreInfo(memory_semaphore);
1006 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1007 if (block == (void *) NULL)
1009 if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1011 UnlockSemaphoreInfo(memory_semaphore);
1012 memory=RelinquishMagickMemory(memory);
1013 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1015 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1016 assert(block != (void *) NULL);
1018 UnlockSemaphoreInfo(memory_semaphore);
1019 memory=RelinquishMagickMemory(memory);
1025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029 % R e s i z e Q u a n t u m M e m o r y %
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 % ResizeQuantumMemory() changes the size of the memory and returns a pointer
1036 % to the (possibly moved) block. The contents will be unchanged up to the
1037 % lesser of the new and old sizes.
1039 % The format of the ResizeQuantumMemory method is:
1041 % void *ResizeQuantumMemory(void *memory,const size_t count,
1042 % const size_t quantum)
1044 % A description of each parameter follows:
1046 % o memory: A pointer to a memory allocation.
1048 % o count: the number of quantum elements to allocate.
1050 % o quantum: the number of bytes in each quantum.
1053 MagickExport void *ResizeQuantumMemory(void *memory,const size_t count,
1054 const size_t quantum)
1060 if ((count == 0) || (quantum != (size/count)))
1062 memory=RelinquishMagickMemory(memory);
1064 return((void *) NULL);
1066 return(ResizeMagickMemory(memory,size));
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074 % S e t M a g i c k M e m o r y M e t h o d s %
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 % SetMagickMemoryMethods() sets the methods to acquire, resize, and destroy
1081 % memory. Your custom memory methods must be set prior to the
1082 % MagickCoreGenesis() method.
1084 % The format of the SetMagickMemoryMethods() method is:
1086 % SetMagickMemoryMethods(AcquireMemoryHandler acquire_memory_handler,
1087 % ResizeMemoryHandler resize_memory_handler,
1088 % DestroyMemoryHandler destroy_memory_handler)
1090 % A description of each parameter follows:
1092 % o acquire_memory_handler: method to acquire memory (e.g. malloc).
1094 % o resize_memory_handler: method to resize memory (e.g. realloc).
1096 % o destroy_memory_handler: method to destroy memory (e.g. free).
1099 MagickExport void SetMagickMemoryMethods(
1100 AcquireMemoryHandler acquire_memory_handler,
1101 ResizeMemoryHandler resize_memory_handler,
1102 DestroyMemoryHandler destroy_memory_handler)
1107 if (acquire_memory_handler != (AcquireMemoryHandler) NULL)
1108 memory_methods.acquire_memory_handler=acquire_memory_handler;
1109 if (resize_memory_handler != (ResizeMemoryHandler) NULL)
1110 memory_methods.resize_memory_handler=resize_memory_handler;
1111 if (destroy_memory_handler != (DestroyMemoryHandler) NULL)
1112 memory_methods.destroy_memory_handler=destroy_memory_handler;