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 MemoryInfo structure. This method always
481 % The format of the AcquireMemoryInfo method is:
483 % MemoryInfo *AcquireMemoryInfo(void)
486 MagickExport MemoryInfo *AcquireMemoryInfo(void)
488 return((MemoryInfo *) NULL);
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 % A c q u i r e Q u a n t u m M e m o r y %
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 % AcquireQuantumMemory() returns a pointer to a block of memory at least
503 % count * quantum bytes suitably aligned for any use.
505 % The format of the AcquireQuantumMemory method is:
507 % void *AcquireQuantumMemory(const size_t count,const size_t quantum)
509 % A description of each parameter follows:
511 % o count: the number of quantum elements to allocate.
513 % o quantum: the number of bytes in each quantum.
516 MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
522 if ((count == 0) || (quantum != (size/count)))
525 return((void *) NULL);
527 return(AcquireMagickMemory(size));
531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
535 % C o p y M a g i c k M e m o r y %
539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
541 % CopyMagickMemory() copies size bytes from memory area source to the
542 % destination. Copying between objects that overlap will take place
543 % correctly. It returns destination.
545 % The format of the CopyMagickMemory method is:
547 % void *CopyMagickMemory(void *destination,const void *source,
550 % A description of each parameter follows:
552 % o destination: the destination.
554 % o source: the source.
556 % o size: the size of the memory in bytes to allocate.
559 MagickExport void *CopyMagickMemory(void *destination,const void *source,
562 register const unsigned char
565 register unsigned char
568 assert(destination != (void *) NULL);
569 assert(source != (const void *) NULL);
570 p=(const unsigned char *) source;
571 q=(unsigned char *) destination;
572 if (((q+size) < p) || (q > (p+size)))
575 default: return(memcpy(destination,source,size));
584 case 0: return(destination);
586 return(memmove(destination,source,size));
590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 + D e s t r o y M a g i c k M e m o r y %
598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600 % DestroyMagickMemory() deallocates memory associated with the memory manager.
602 % The format of the DestroyMagickMemory method is:
604 % DestroyMagickMemory(void)
607 MagickExport void DestroyMagickMemory(void)
609 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
613 if (memory_semaphore == (SemaphoreInfo *) NULL)
614 AcquireSemaphoreInfo(&memory_semaphore);
615 LockSemaphoreInfo(memory_semaphore);
616 UnlockSemaphoreInfo(memory_semaphore);
617 for (i=0; i < (ssize_t) memory_pool.number_segments; i++)
618 if (memory_pool.segments[i]->mapped == MagickFalse)
619 memory_methods.destroy_memory_handler(
620 memory_pool.segments[i]->allocation);
622 (void) UnmapBlob(memory_pool.segments[i]->allocation,
623 memory_pool.segments[i]->length);
624 free_segments=(DataSegmentInfo *) NULL;
625 (void) ResetMagickMemory(&memory_pool,0,sizeof(memory_pool));
626 DestroySemaphoreInfo(&memory_semaphore);
630 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 + E x p a n d H e a p %
640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642 % ExpandHeap() get more memory from the system. It returns MagickTrue on
643 % success otherwise MagickFalse.
645 % The format of the ExpandHeap method is:
647 % MagickBooleanType ExpandHeap(size_t size)
649 % A description of each parameter follows:
651 % o size: the size of the memory in bytes we require.
654 static MagickBooleanType ExpandHeap(size_t size)
674 blocksize=((size+12*sizeof(size_t))+SegmentSize-1) & -SegmentSize;
675 assert(memory_pool.number_segments < MaxSegments);
676 segment=MapBlob(-1,IOMode,0,blocksize);
677 mapped=segment != (void *) NULL ? MagickTrue : MagickFalse;
678 if (segment == (void *) NULL)
679 segment=(void *) memory_methods.acquire_memory_handler(blocksize);
680 if (segment == (void *) NULL)
682 segment_info=(DataSegmentInfo *) free_segments;
683 free_segments=segment_info->next;
684 segment_info->mapped=mapped;
685 segment_info->length=blocksize;
686 segment_info->allocation=segment;
687 segment_info->bound=(char *) segment+blocksize;
688 i=(ssize_t) memory_pool.number_segments-1;
689 for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
690 memory_pool.segments[i+1]=memory_pool.segments[i];
691 memory_pool.segments[i+1]=segment_info;
692 memory_pool.number_segments++;
693 size=blocksize-12*sizeof(size_t);
694 block=(char *) segment_info->allocation+4*sizeof(size_t);
695 *BlockHeader(block)=size | PreviousBlockBit;
696 *BlockFooter(block,size)=size;
697 InsertFreeBlock(block,AllocationPolicy(size));
698 block=NextBlock(block);
699 assert(block < segment_info->bound);
700 *BlockHeader(block)=2*sizeof(size_t);
701 *BlockHeader(NextBlock(block))=PreviousBlockBit;
707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
711 % G e t M a g i c k M e m o r y M e t h o d s %
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
717 % GetMagickMemoryMethods() gets the methods to acquire, resize, and destroy
720 % The format of the GetMagickMemoryMethods() method is:
722 % void GetMagickMemoryMethods(AcquireMemoryHandler *acquire_memory_handler,
723 % ResizeMemoryHandler *resize_memory_handler,
724 % DestroyMemoryHandler *destroy_memory_handler)
726 % A description of each parameter follows:
728 % o acquire_memory_handler: method to acquire memory (e.g. malloc).
730 % o resize_memory_handler: method to resize memory (e.g. realloc).
732 % o destroy_memory_handler: method to destroy memory (e.g. free).
735 MagickExport void GetMagickMemoryMethods(
736 AcquireMemoryHandler *acquire_memory_handler,
737 ResizeMemoryHandler *resize_memory_handler,
738 DestroyMemoryHandler *destroy_memory_handler)
740 assert(acquire_memory_handler != (AcquireMemoryHandler *) NULL);
741 assert(resize_memory_handler != (ResizeMemoryHandler *) NULL);
742 assert(destroy_memory_handler != (DestroyMemoryHandler *) NULL);
743 *acquire_memory_handler=memory_methods.acquire_memory_handler;
744 *resize_memory_handler=memory_methods.resize_memory_handler;
745 *destroy_memory_handler=memory_methods.destroy_memory_handler;
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
753 % G e t M e m o r y I n f o M e m o r y %
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 % GetMemoryInfoMemory() returns a pointer to a block of memory at least size
760 % bytes suitably aligned for any use.
762 % The format of the GetMemoryInfoMemory method is:
764 % void *GetMemoryInfoMemory(const MemoryInfo *memory_info,
765 % const size_t count,const size_t quantum)
767 % A description of each parameter follows:
769 % o memory: A pointer to a block of memory to free for reuse.
771 % o count: the number of quantum elements to allocate.
773 % o quantum: the number of bytes in each quantum.
775 MagickExport void *GetMemoryInfoMemory(const MemoryInfo *memory_info,
776 const size_t count,const size_t quantum)
778 assert(memory_info != (const MemoryInfo *) NULL);
779 return(memory_info->memory);
783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787 % R e l i n q u i s h A l i g n e d M e m o r y %
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793 % RelinquishAlignedMemory() frees memory acquired with AcquireAlignedMemory()
796 % The format of the RelinquishAlignedMemory method is:
798 % void *RelinquishAlignedMemory(void *memory)
800 % A description of each parameter follows:
802 % o memory: A pointer to a block of memory to free for reuse.
805 MagickExport void *RelinquishAlignedMemory(void *memory)
807 if (memory == (void *) NULL)
808 return((void *) NULL);
809 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
811 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
812 _aligned_free(memory);
814 free(*((void **) memory-1));
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 % R e l i n q u i s h M a g i c k M e m o r y %
828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
831 % or AcquireQuantumMemory() for reuse.
833 % The format of the RelinquishMagickMemory method is:
835 % void *RelinquishMagickMemory(void *memory)
837 % A description of each parameter follows:
839 % o memory: A pointer to a block of memory to free for reuse.
842 MagickExport void *RelinquishMagickMemory(void *memory)
844 if (memory == (void *) NULL)
845 return((void *) NULL);
846 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
847 memory_methods.destroy_memory_handler(memory);
849 LockSemaphoreInfo(memory_semaphore);
850 assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
851 assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
852 if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
858 Coalesce with previous adjacent block.
860 previous=PreviousBlock(memory);
861 RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
862 *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
863 (*BlockHeader(previous) & ~SizeMask);
866 if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
872 Coalesce with next adjacent block.
874 next=NextBlock(memory);
875 RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
876 *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
877 (*BlockHeader(memory) & ~SizeMask);
879 *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
880 *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
881 InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
882 UnlockSemaphoreInfo(memory_semaphore);
884 return((void *) NULL);
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 % R e l i n q u i s h V i r t u a l M e m o r y %
896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898 % RelinquishMemoryInfo() frees memory acquired with AcquireMemoryInfo()
901 % The format of the RelinquishMemoryInfo method is:
903 % void *RelinquishMemoryInfo(const MemoryInfo *memory_info)
905 % A description of each parameter follows:
907 % o memory_info: A pointer to a block of memory to free for reuse.
910 MagickExport MemoryInfo *RelinquishMemoryInfo(const MemoryInfo *memory_info)
912 return((MemoryInfo *) NULL);
916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920 % R e s e t M a g i c k M e m o r y %
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 % ResetMagickMemory() fills the first size bytes of the memory area pointed to
927 % by memory with the constant byte c.
929 % The format of the ResetMagickMemory method is:
931 % void *ResetMagickMemory(void *memory,int byte,const size_t size)
933 % A description of each parameter follows:
935 % o memory: a pointer to a memory allocation.
937 % o byte: set the memory to this value.
939 % o size: size of the memory to reset.
942 MagickExport void *ResetMagickMemory(void *memory,int byte,const size_t size)
944 assert(memory != (void *) NULL);
945 return(memset(memory,byte,size));
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 % R e s i z e M a g i c k M e m o r y %
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 % ResizeMagickMemory() changes the size of the memory and returns a pointer to
960 % the (possibly moved) block. The contents will be unchanged up to the
961 % lesser of the new and old sizes.
963 % The format of the ResizeMagickMemory method is:
965 % void *ResizeMagickMemory(void *memory,const size_t size)
967 % A description of each parameter follows:
969 % o memory: A pointer to a memory allocation.
971 % o size: the new size of the allocated memory.
975 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
976 static inline void *ResizeBlock(void *block,size_t size)
981 if (block == (void *) NULL)
982 return(AcquireBlock(size));
983 memory=AcquireBlock(size);
984 if (memory == (void *) NULL)
985 return((void *) NULL);
986 if (size <= (SizeOfBlock(block)-sizeof(size_t)))
987 (void) memcpy(memory,block,size);
989 (void) memcpy(memory,block,SizeOfBlock(block)-sizeof(size_t));
990 memory_pool.allocation+=size;
995 MagickExport void *ResizeMagickMemory(void *memory,const size_t size)
1000 if (memory == (void *) NULL)
1001 return(AcquireMagickMemory(size));
1002 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
1003 block=memory_methods.resize_memory_handler(memory,size == 0 ? 1UL : size);
1004 if (block == (void *) NULL)
1005 memory=RelinquishMagickMemory(memory);
1007 LockSemaphoreInfo(memory_semaphore);
1008 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1009 if (block == (void *) NULL)
1011 if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1013 UnlockSemaphoreInfo(memory_semaphore);
1014 memory=RelinquishMagickMemory(memory);
1015 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1017 block=ResizeBlock(memory,size == 0 ? 1UL : size);
1018 assert(block != (void *) NULL);
1020 UnlockSemaphoreInfo(memory_semaphore);
1021 memory=RelinquishMagickMemory(memory);
1027 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 % R e s i z e Q u a n t u m M e m o r y %
1035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037 % ResizeQuantumMemory() changes the size of the memory and returns a pointer
1038 % to the (possibly moved) block. The contents will be unchanged up to the
1039 % lesser of the new and old sizes.
1041 % The format of the ResizeQuantumMemory method is:
1043 % void *ResizeQuantumMemory(void *memory,const size_t count,
1044 % const size_t quantum)
1046 % A description of each parameter follows:
1048 % o memory: A pointer to a memory allocation.
1050 % o count: the number of quantum elements to allocate.
1052 % o quantum: the number of bytes in each quantum.
1055 MagickExport void *ResizeQuantumMemory(void *memory,const size_t count,
1056 const size_t quantum)
1062 if ((count == 0) || (quantum != (size/count)))
1064 memory=RelinquishMagickMemory(memory);
1066 return((void *) NULL);
1068 return(ResizeMagickMemory(memory,size));
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % S e t M a g i c k M e m o r y M e t h o d s %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082 % SetMagickMemoryMethods() sets the methods to acquire, resize, and destroy
1083 % memory. Your custom memory methods must be set prior to the
1084 % MagickCoreGenesis() method.
1086 % The format of the SetMagickMemoryMethods() method is:
1088 % SetMagickMemoryMethods(AcquireMemoryHandler acquire_memory_handler,
1089 % ResizeMemoryHandler resize_memory_handler,
1090 % DestroyMemoryHandler destroy_memory_handler)
1092 % A description of each parameter follows:
1094 % o acquire_memory_handler: method to acquire memory (e.g. malloc).
1096 % o resize_memory_handler: method to resize memory (e.g. realloc).
1098 % o destroy_memory_handler: method to destroy memory (e.g. free).
1101 MagickExport void SetMagickMemoryMethods(
1102 AcquireMemoryHandler acquire_memory_handler,
1103 ResizeMemoryHandler resize_memory_handler,
1104 DestroyMemoryHandler destroy_memory_handler)
1109 if (acquire_memory_handler != (AcquireMemoryHandler) NULL)
1110 memory_methods.acquire_memory_handler=acquire_memory_handler;
1111 if (resize_memory_handler != (ResizeMemoryHandler) NULL)
1112 memory_methods.resize_memory_handler=resize_memory_handler;
1113 if (destroy_memory_handler != (DestroyMemoryHandler) NULL)
1114 memory_methods.destroy_memory_handler=destroy_memory_handler;