]> granicus.if.org Git - imagemagick/blob - MagickCore/memory.c
(no commit message)
[imagemagick] / MagickCore / memory.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
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                   %
11 %                                                                             %
12 %                                                                             %
13 %                     MagickCore Memory Allocation Methods                    %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                                 July 1998                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    http://www.imagemagick.org/script/license.php                            %
27 %                                                                             %
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.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
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
38 %  memory corruption.
39 %
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.
45 %
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
49 %  heap.
50 %
51 */
52 \f
53 /*
54   Include declarations.
55 */
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"
65 \f
66 /*
67   Define declarations.
68 */
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)
86 \f
87 /*
88   Typedef declarations.
89 */
90 typedef struct _DataSegmentInfo
91 {
92   void
93     *allocation,
94     *bound;
95
96   MagickBooleanType
97     mapped;
98
99   size_t
100     length;
101
102   struct _DataSegmentInfo
103     *previous,
104     *next;
105 } DataSegmentInfo;
106
107 typedef struct _MagickMemoryMethods
108 {
109   AcquireMemoryHandler
110     acquire_memory_handler;
111
112   ResizeMemoryHandler
113     resize_memory_handler;
114
115   DestroyMemoryHandler
116     destroy_memory_handler;
117 } MagickMemoryMethods;
118
119 typedef struct _MemoryInfo
120 {
121   char
122     filename[MaxTextExtent];
123
124   MagickBooleanType
125     mapped;
126
127   void
128     *memory;
129 } MemoryInfo;
130
131 typedef struct _MemoryPool
132 {
133   size_t
134     allocation;
135
136   void
137     *blocks[MaxBlocks+1];
138
139   size_t
140     number_segments;
141
142   DataSegmentInfo
143     *segments[MaxSegments],
144     segment_pool[MaxSegments];
145 } MemoryPool;
146 \f
147 /*
148   Global declarations.
149 */
150 static MagickMemoryMethods
151   memory_methods =
152   {
153     (AcquireMemoryHandler) malloc,
154     (ResizeMemoryHandler) realloc,
155     (DestroyMemoryHandler) free
156   };
157
158 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
159 static MemoryPool
160   memory_pool;
161
162 static SemaphoreInfo
163   *memory_semaphore = (SemaphoreInfo *) NULL;
164
165 static volatile DataSegmentInfo
166   *free_segments = (DataSegmentInfo *) NULL;
167 \f
168 /*
169   Forward declarations.
170 */
171 static MagickBooleanType
172   ExpandHeap(size_t);
173 #endif
174 \f
175 /*
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 %                                                                             %
178 %                                                                             %
179 %                                                                             %
180 %   A c q u i r e A l i g n e d M e m o r y                                   %
181 %                                                                             %
182 %                                                                             %
183 %                                                                             %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 %
186 %  AcquireAlignedMemory() returns a pointer to a block of memory at least size
187 %  bytes whose address is a multiple of 16*sizeof(void *).
188 %
189 %  The format of the AcquireAlignedMemory method is:
190 %
191 %      void *AcquireAlignedMemory(const size_t count,const size_t quantum)
192 %
193 %  A description of each parameter follows:
194 %
195 %    o count: the number of quantum elements to allocate.
196 %
197 %    o quantum: the number of bytes in each quantum.
198 %
199 */
200 MagickExport void *AcquireAlignedMemory(const size_t count,const size_t quantum)
201 {
202 #define AlignedExtent(size,alignment) \
203   (((size)+((alignment)-1)) & ~((alignment)-1))
204
205   size_t
206     alignment,
207     extent,
208     size;
209
210   void
211     *memory;
212
213   size=count*quantum;
214   if ((count == 0) || (quantum != (size/count)))
215     {
216       errno=ENOMEM;
217       return((void *) NULL);
218     }
219   memory=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)
226     memory=NULL;
227 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
228   memory=_aligned_malloc(extent,alignment);
229 #else
230   {
231     void
232       *p;
233
234     extent=(size+alignment-1)+sizeof(void *);
235     if (extent > size)
236       {
237         p=malloc(extent);
238         if (p != NULL)
239           {
240             memory=(void *) AlignedExtent((size_t) p+sizeof(void *),alignment);
241             *((void **) memory-1)=p;
242           }
243       }
244   }
245 #endif
246   return(memory);
247 }
248 \f
249 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %                                                                             %
253 %                                                                             %
254 %                                                                             %
255 +   A c q u i r e B l o c k                                                   %
256 %                                                                             %
257 %                                                                             %
258 %                                                                             %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 %  AcquireBlock() returns a pointer to a block of memory at least size bytes
262 %  suitably aligned for any use.
263 %
264 %  The format of the AcquireBlock method is:
265 %
266 %      void *AcquireBlock(const size_t size)
267 %
268 %  A description of each parameter follows:
269 %
270 %    o size: the size of the memory in bytes to allocate.
271 %
272 */
273
274 static inline size_t AllocationPolicy(size_t size)
275 {
276   register size_t
277     blocksize;
278
279   /*
280     The linear distribution.
281   */
282   assert(size != 0);
283   assert(size % (4*sizeof(size_t)) == 0);
284   if (size <= BlockThreshold)
285     return(size/(4*sizeof(size_t)));
286   /*
287     Check for the largest block size.
288   */
289   if (size > (size_t) (BlockThreshold*(1L << (MaxBlockExponent-1L))))
290     return(MaxBlocks-1L);
291   /*
292     Otherwise use a power of two distribution.
293   */
294   blocksize=BlockThreshold/(4*sizeof(size_t));
295   for ( ; size > BlockThreshold; size/=2)
296     blocksize++;
297   assert(blocksize > (BlockThreshold/(4*sizeof(size_t))));
298   assert(blocksize < (MaxBlocks-1L));
299   return(blocksize);
300 }
301
302 static inline void InsertFreeBlock(void *block,const size_t i)
303 {
304   register void
305     *next,
306     *previous;
307
308   size_t
309     size;
310
311   size=SizeOfBlock(block);
312   previous=(void *) NULL;
313   next=memory_pool.blocks[i];
314   while ((next != (void *) NULL) && (SizeOfBlock(next) < size))
315   {
316     previous=next;
317     next=NextBlockInList(next);
318   }
319   PreviousBlockInList(block)=previous;
320   NextBlockInList(block)=next;
321   if (previous != (void *) NULL)
322     NextBlockInList(previous)=block;
323   else
324     memory_pool.blocks[i]=block;
325   if (next != (void *) NULL)
326     PreviousBlockInList(next)=block;
327 }
328
329 static inline void RemoveFreeBlock(void *block,const size_t i)
330 {
331   register void
332     *next,
333     *previous;
334
335   next=NextBlockInList(block);
336   previous=PreviousBlockInList(block);
337   if (previous == (void *) NULL)
338     memory_pool.blocks[i]=next;
339   else
340     NextBlockInList(previous)=next;
341   if (next != (void *) NULL)
342     PreviousBlockInList(next)=previous;
343 }
344
345 static void *AcquireBlock(size_t size)
346 {
347   register size_t
348     i;
349
350   register void
351     *block;
352
353   /*
354     Find free block.
355   */
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)
362     {
363       i++;
364       while (memory_pool.blocks[i] == (void *) NULL)
365         i++;
366       block=memory_pool.blocks[i];
367       if (i >= MaxBlocks)
368         return((void *) NULL);
369     }
370   assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
371   assert(SizeOfBlock(block) >= size);
372   RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
373   if (SizeOfBlock(block) > size)
374     {
375       size_t
376         blocksize;
377
378       void
379         *next;
380
381       /*
382         Split block.
383       */
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);
390     }
391   assert(size == SizeOfBlock(block));
392   *BlockHeader(NextBlock(block))|=PreviousBlockBit;
393   memory_pool.allocation+=size;
394   return(block);
395 }
396 #endif
397 \f
398 /*
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 %                                                                             %
401 %                                                                             %
402 %                                                                             %
403 %   A c q u i r e M a g i c k M e m o r y                                     %
404 %                                                                             %
405 %                                                                             %
406 %                                                                             %
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 %
409 %  AcquireMagickMemory() returns a pointer to a block of memory at least size
410 %  bytes suitably aligned for any use.
411 %
412 %  The format of the AcquireMagickMemory method is:
413 %
414 %      void *AcquireMagickMemory(const size_t size)
415 %
416 %  A description of each parameter follows:
417 %
418 %    o size: the size of the memory in bytes to allocate.
419 %
420 */
421 MagickExport void *AcquireMagickMemory(const size_t size)
422 {
423   register void
424     *memory;
425
426 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
427   memory=memory_methods.acquire_memory_handler(size == 0 ? 1UL : size);
428 #else
429   if (memory_semaphore == (SemaphoreInfo *) NULL)
430     AcquireSemaphoreInfo(&memory_semaphore);
431   if (free_segments == (DataSegmentInfo *) NULL)
432     {
433       LockSemaphoreInfo(memory_semaphore);
434       if (free_segments == (DataSegmentInfo *) NULL)
435         {
436           register ssize_t
437             i;
438
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++)
444           {
445             if (i != 0)
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]);
450           }
451           free_segments=(&memory_pool.segment_pool[0]);
452         }
453       UnlockSemaphoreInfo(memory_semaphore);
454     }
455   LockSemaphoreInfo(memory_semaphore);
456   memory=AcquireBlock(size == 0 ? 1UL : size);
457   if (memory == (void *) NULL)
458     {
459       if (ExpandHeap(size == 0 ? 1UL : size) != MagickFalse)
460         memory=AcquireBlock(size == 0 ? 1UL : size);
461     }
462   UnlockSemaphoreInfo(memory_semaphore);
463 #endif
464   return(memory);
465 }
466 \f
467 /*
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469 %                                                                             %
470 %                                                                             %
471 %                                                                             %
472 %   A c q u i r e M e m o r y I n f o                                         %
473 %                                                                             %
474 %                                                                             %
475 %                                                                             %
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 %
478 %  AcquireMemoryInfo() returns a MemoryInfo structure.  This method always
479 %  succeeds.
480 %
481 %  The format of the AcquireMemoryInfo method is:
482 %
483 %      MemoryInfo *AcquireMemoryInfo(void)
484 %
485 */
486 MagickExport MemoryInfo *AcquireMemoryInfo(void)
487 {
488   return((MemoryInfo *) NULL);
489 }
490 \f
491 /*
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 %                                                                             %
494 %                                                                             %
495 %                                                                             %
496 %   A c q u i r e Q u a n t u m M e m o r y                                   %
497 %                                                                             %
498 %                                                                             %
499 %                                                                             %
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501 %
502 %  AcquireQuantumMemory() returns a pointer to a block of memory at least
503 %  count * quantum bytes suitably aligned for any use.
504 %
505 %  The format of the AcquireQuantumMemory method is:
506 %
507 %      void *AcquireQuantumMemory(const size_t count,const size_t quantum)
508 %
509 %  A description of each parameter follows:
510 %
511 %    o count: the number of quantum elements to allocate.
512 %
513 %    o quantum: the number of bytes in each quantum.
514 %
515 */
516 MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
517 {
518   size_t
519     size;
520
521   size=count*quantum;
522   if ((count == 0) || (quantum != (size/count)))
523     {
524       errno=ENOMEM;
525       return((void *) NULL);
526     }
527   return(AcquireMagickMemory(size));
528 }
529 \f
530 /*
531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532 %                                                                             %
533 %                                                                             %
534 %                                                                             %
535 %   C o p y M a g i c k M e m o r y                                           %
536 %                                                                             %
537 %                                                                             %
538 %                                                                             %
539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540 %
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.
544 %
545 %  The format of the CopyMagickMemory method is:
546 %
547 %      void *CopyMagickMemory(void *destination,const void *source,
548 %        const size_t size)
549 %
550 %  A description of each parameter follows:
551 %
552 %    o destination: the destination.
553 %
554 %    o source: the source.
555 %
556 %    o size: the size of the memory in bytes to allocate.
557 %
558 */
559 MagickExport void *CopyMagickMemory(void *destination,const void *source,
560   const size_t size)
561 {
562   register const unsigned char
563     *p;
564
565   register unsigned char
566     *q;
567
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)))
573     switch (size)
574     {
575       default: return(memcpy(destination,source,size));
576       case 8: *q++=(*p++);
577       case 7: *q++=(*p++);
578       case 6: *q++=(*p++);
579       case 5: *q++=(*p++);
580       case 4: *q++=(*p++);
581       case 3: *q++=(*p++);
582       case 2: *q++=(*p++);
583       case 1: *q++=(*p++);
584       case 0: return(destination);
585     }
586   return(memmove(destination,source,size));
587 }
588 \f
589 /*
590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 %                                                                             %
592 %                                                                             %
593 %                                                                             %
594 +   D e s t r o y M a g i c k M e m o r y                                     %
595 %                                                                             %
596 %                                                                             %
597 %                                                                             %
598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
599 %
600 %  DestroyMagickMemory() deallocates memory associated with the memory manager.
601 %
602 %  The format of the DestroyMagickMemory method is:
603 %
604 %      DestroyMagickMemory(void)
605 %
606 */
607 MagickExport void DestroyMagickMemory(void)
608 {
609 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
610   register ssize_t
611     i;
612
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);
621     else
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);
627 #endif
628 }
629 \f
630 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
631 /*
632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 %                                                                             %
634 %                                                                             %
635 %                                                                             %
636 +   E x p a n d H e a p                                                       %
637 %                                                                             %
638 %                                                                             %
639 %                                                                             %
640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 %
642 %  ExpandHeap() get more memory from the system.  It returns MagickTrue on
643 %  success otherwise MagickFalse.
644 %
645 %  The format of the ExpandHeap method is:
646 %
647 %      MagickBooleanType ExpandHeap(size_t size)
648 %
649 %  A description of each parameter follows:
650 %
651 %    o size: the size of the memory in bytes we require.
652 %
653 */
654 static MagickBooleanType ExpandHeap(size_t size)
655 {
656   DataSegmentInfo
657     *segment_info;
658
659   MagickBooleanType
660     mapped;
661
662   register ssize_t
663     i;
664
665   register void
666     *block;
667
668   size_t
669     blocksize;
670
671   void
672     *segment;
673
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)
681     return(MagickFalse);
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;
702   return(MagickTrue);
703 }
704 #endif
705 \f
706 /*
707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 %                                                                             %
709 %                                                                             %
710 %                                                                             %
711 %   G e t M a g i c k M e m o r y M e t h o d s                               %
712 %                                                                             %
713 %                                                                             %
714 %                                                                             %
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 %
717 %  GetMagickMemoryMethods() gets the methods to acquire, resize, and destroy
718 %  memory.
719 %
720 %  The format of the GetMagickMemoryMethods() method is:
721 %
722 %      void GetMagickMemoryMethods(AcquireMemoryHandler *acquire_memory_handler,
723 %        ResizeMemoryHandler *resize_memory_handler,
724 %        DestroyMemoryHandler *destroy_memory_handler)
725 %
726 %  A description of each parameter follows:
727 %
728 %    o acquire_memory_handler: method to acquire memory (e.g. malloc).
729 %
730 %    o resize_memory_handler: method to resize memory (e.g. realloc).
731 %
732 %    o destroy_memory_handler: method to destroy memory (e.g. free).
733 %
734 */
735 MagickExport void GetMagickMemoryMethods(
736   AcquireMemoryHandler *acquire_memory_handler,
737   ResizeMemoryHandler *resize_memory_handler,
738   DestroyMemoryHandler *destroy_memory_handler)
739 {
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;
746 }
747 \f
748 /*
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750 %                                                                             %
751 %                                                                             %
752 %                                                                             %
753 %   G e t M e m o r y I n f o M e m o r y                                     %
754 %                                                                             %
755 %                                                                             %
756 %                                                                             %
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 %
759 %  GetMemoryInfoMemory() returns a pointer to a block of memory at least size
760 %  bytes suitably aligned for any use.
761 %
762 %  The format of the GetMemoryInfoMemory method is:
763 %
764 %      void *GetMemoryInfoMemory(const MemoryInfo *memory_info,
765 %        const size_t count,const size_t quantum)
766 %
767 %  A description of each parameter follows:
768 %
769 %    o memory: A pointer to a block of memory to free for reuse.
770 %
771 %    o count: the number of quantum elements to allocate.
772 %
773 %    o quantum: the number of bytes in each quantum.
774 */
775 MagickExport void *GetMemoryInfoMemory(const MemoryInfo *memory_info,
776   const size_t count,const size_t quantum)
777 {
778   assert(memory_info != (const MemoryInfo *) NULL);
779   return(memory_info->memory);
780 }
781 \f
782 /*
783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784 %                                                                             %
785 %                                                                             %
786 %                                                                             %
787 %   R e l i n q u i s h A l i g n e d M e m o r y                             %
788 %                                                                             %
789 %                                                                             %
790 %                                                                             %
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792 %
793 %  RelinquishAlignedMemory() frees memory acquired with AcquireAlignedMemory()
794 %  or reuse.
795 %
796 %  The format of the RelinquishAlignedMemory method is:
797 %
798 %      void *RelinquishAlignedMemory(void *memory)
799 %
800 %  A description of each parameter follows:
801 %
802 %    o memory: A pointer to a block of memory to free for reuse.
803 %
804 */
805 MagickExport void *RelinquishAlignedMemory(void *memory)
806 {
807   if (memory == (void *) NULL)
808     return((void *) NULL);
809 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
810   free(memory);
811 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
812   _aligned_free(memory);
813 #else
814   free(*((void **) memory-1));
815 #endif
816   return(NULL);
817 }
818 \f
819 /*
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821 %                                                                             %
822 %                                                                             %
823 %                                                                             %
824 %   R e l i n q u i s h M a g i c k M e m o r y                               %
825 %                                                                             %
826 %                                                                             %
827 %                                                                             %
828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829 %
830 %  RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
831 %  or AcquireQuantumMemory() for reuse.
832 %
833 %  The format of the RelinquishMagickMemory method is:
834 %
835 %      void *RelinquishMagickMemory(void *memory)
836 %
837 %  A description of each parameter follows:
838 %
839 %    o memory: A pointer to a block of memory to free for reuse.
840 %
841 */
842 MagickExport void *RelinquishMagickMemory(void *memory)
843 {
844   if (memory == (void *) NULL)
845     return((void *) NULL);
846 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
847   memory_methods.destroy_memory_handler(memory);
848 #else
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)
853     {
854       void
855         *previous;
856
857       /*
858         Coalesce with previous adjacent block.
859       */
860       previous=PreviousBlock(memory);
861       RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
862       *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
863         (*BlockHeader(previous) & ~SizeMask);
864       memory=previous;
865     }
866   if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
867     {
868       void
869         *next;
870
871       /*
872         Coalesce with next adjacent block.
873       */
874       next=NextBlock(memory);
875       RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
876       *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
877         (*BlockHeader(memory) & ~SizeMask);
878     }
879   *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
880   *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
881   InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
882   UnlockSemaphoreInfo(memory_semaphore);
883 #endif
884   return((void *) NULL);
885 }
886 \f
887 /*
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 %                                                                             %
890 %                                                                             %
891 %                                                                             %
892 %   R e l i n q u i s h V i r t u a l M e m o r y                             %
893 %                                                                             %
894 %                                                                             %
895 %                                                                             %
896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897 %
898 %  RelinquishMemoryInfo() frees memory acquired with AcquireMemoryInfo()
899 %  or reuse.
900 %
901 %  The format of the RelinquishMemoryInfo method is:
902 %
903 %      void *RelinquishMemoryInfo(const MemoryInfo *memory_info)
904 %
905 %  A description of each parameter follows:
906 %
907 %    o memory_info: A pointer to a block of memory to free for reuse.
908 %
909 */
910 MagickExport MemoryInfo *RelinquishMemoryInfo(const MemoryInfo *memory_info)
911 {
912   return((MemoryInfo *) NULL);
913 }
914 \f
915 /*
916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
917 %                                                                             %
918 %                                                                             %
919 %                                                                             %
920 %   R e s e t M a g i c k M e m o r y                                         %
921 %                                                                             %
922 %                                                                             %
923 %                                                                             %
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
925 %
926 %  ResetMagickMemory() fills the first size bytes of the memory area pointed to
927 %  by memory with the constant byte c.
928 %
929 %  The format of the ResetMagickMemory method is:
930 %
931 %      void *ResetMagickMemory(void *memory,int byte,const size_t size)
932 %
933 %  A description of each parameter follows:
934 %
935 %    o memory: a pointer to a memory allocation.
936 %
937 %    o byte: set the memory to this value.
938 %
939 %    o size: size of the memory to reset.
940 %
941 */
942 MagickExport void *ResetMagickMemory(void *memory,int byte,const size_t size)
943 {
944   assert(memory != (void *) NULL);
945   return(memset(memory,byte,size));
946 }
947 \f
948 /*
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950 %                                                                             %
951 %                                                                             %
952 %                                                                             %
953 %   R e s i z e M a g i c k M e m o r y                                       %
954 %                                                                             %
955 %                                                                             %
956 %                                                                             %
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
958 %
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.
962 %
963 %  The format of the ResizeMagickMemory method is:
964 %
965 %      void *ResizeMagickMemory(void *memory,const size_t size)
966 %
967 %  A description of each parameter follows:
968 %
969 %    o memory: A pointer to a memory allocation.
970 %
971 %    o size: the new size of the allocated memory.
972 %
973 */
974
975 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
976 static inline void *ResizeBlock(void *block,size_t size)
977 {
978   register void
979     *memory;
980
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);
988   else
989     (void) memcpy(memory,block,SizeOfBlock(block)-sizeof(size_t));
990   memory_pool.allocation+=size;
991   return(memory);
992 }
993 #endif
994
995 MagickExport void *ResizeMagickMemory(void *memory,const size_t size)
996 {
997   register void
998     *block;
999
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);
1006 #else
1007   LockSemaphoreInfo(memory_semaphore);
1008   block=ResizeBlock(memory,size == 0 ? 1UL : size);
1009   if (block == (void *) NULL)
1010     {
1011       if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1012         {
1013           UnlockSemaphoreInfo(memory_semaphore);
1014           memory=RelinquishMagickMemory(memory);
1015           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1016         }
1017       block=ResizeBlock(memory,size == 0 ? 1UL : size);
1018       assert(block != (void *) NULL);
1019     }
1020   UnlockSemaphoreInfo(memory_semaphore);
1021   memory=RelinquishMagickMemory(memory);
1022 #endif
1023   return(block);
1024 }
1025 \f
1026 /*
1027 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028 %                                                                             %
1029 %                                                                             %
1030 %                                                                             %
1031 %   R e s i z e Q u a n t u m M e m o r y                                     %
1032 %                                                                             %
1033 %                                                                             %
1034 %                                                                             %
1035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1036 %
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.
1040 %
1041 %  The format of the ResizeQuantumMemory method is:
1042 %
1043 %      void *ResizeQuantumMemory(void *memory,const size_t count,
1044 %        const size_t quantum)
1045 %
1046 %  A description of each parameter follows:
1047 %
1048 %    o memory: A pointer to a memory allocation.
1049 %
1050 %    o count: the number of quantum elements to allocate.
1051 %
1052 %    o quantum: the number of bytes in each quantum.
1053 %
1054 */
1055 MagickExport void *ResizeQuantumMemory(void *memory,const size_t count,
1056   const size_t quantum)
1057 {
1058   size_t
1059     size;
1060
1061   size=count*quantum;
1062   if ((count == 0) || (quantum != (size/count)))
1063     {
1064       memory=RelinquishMagickMemory(memory);
1065       errno=ENOMEM;
1066       return((void *) NULL);
1067     }
1068   return(ResizeMagickMemory(memory,size));
1069 }
1070 \f
1071 /*
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073 %                                                                             %
1074 %                                                                             %
1075 %                                                                             %
1076 %   S e t M a g i c k M e m o r y M e t h o d s                               %
1077 %                                                                             %
1078 %                                                                             %
1079 %                                                                             %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 %
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.
1085 %
1086 %  The format of the SetMagickMemoryMethods() method is:
1087 %
1088 %      SetMagickMemoryMethods(AcquireMemoryHandler acquire_memory_handler,
1089 %        ResizeMemoryHandler resize_memory_handler,
1090 %        DestroyMemoryHandler destroy_memory_handler)
1091 %
1092 %  A description of each parameter follows:
1093 %
1094 %    o acquire_memory_handler: method to acquire memory (e.g. malloc).
1095 %
1096 %    o resize_memory_handler: method to resize memory (e.g. realloc).
1097 %
1098 %    o destroy_memory_handler: method to destroy memory (e.g. free).
1099 %
1100 */
1101 MagickExport void SetMagickMemoryMethods(
1102   AcquireMemoryHandler acquire_memory_handler,
1103   ResizeMemoryHandler resize_memory_handler,
1104   DestroyMemoryHandler destroy_memory_handler)
1105 {
1106   /*
1107     Set memory methods.
1108   */
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;
1115 }