]> granicus.if.org Git - imagemagick/blob - MagickCore/memory.c
a315c49118c039336f589e679151670f6fc75340
[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 pointer to a block of memory at least size
479 %  bytes suitably aligned for any use.
480 %
481 %  The format of the AcquireMemoryInfo method is:
482 %
483 %      MagickInfo *AcquireMemoryInfo(const size_t size)
484 %
485 %  A description of each parameter follows:
486 %
487 %    o size: the size of the virtual memory in bytes to allocate.
488 %
489 */
490 MagickExport MemoryInfo *AcquireMemoryInfo(const size_t size)
491 {
492   return((MemoryInfo *) NULL);
493 }
494 \f
495 /*
496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 %                                                                             %
498 %                                                                             %
499 %                                                                             %
500 %   A c q u i r e Q u a n t u m M e m o r y                                   %
501 %                                                                             %
502 %                                                                             %
503 %                                                                             %
504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505 %
506 %  AcquireQuantumMemory() returns a pointer to a block of memory at least
507 %  count * quantum bytes suitably aligned for any use.
508 %
509 %  The format of the AcquireQuantumMemory method is:
510 %
511 %      void *AcquireQuantumMemory(const size_t count,const size_t quantum)
512 %
513 %  A description of each parameter follows:
514 %
515 %    o count: the number of quantum elements to allocate.
516 %
517 %    o quantum: the number of bytes in each quantum.
518 %
519 */
520 MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
521 {
522   size_t
523     size;
524
525   size=count*quantum;
526   if ((count == 0) || (quantum != (size/count)))
527     {
528       errno=ENOMEM;
529       return((void *) NULL);
530     }
531   return(AcquireMagickMemory(size));
532 }
533 \f
534 /*
535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536 %                                                                             %
537 %                                                                             %
538 %                                                                             %
539 %   C o p y M a g i c k M e m o r y                                           %
540 %                                                                             %
541 %                                                                             %
542 %                                                                             %
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 %
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.
548 %
549 %  The format of the CopyMagickMemory method is:
550 %
551 %      void *CopyMagickMemory(void *destination,const void *source,
552 %        const size_t size)
553 %
554 %  A description of each parameter follows:
555 %
556 %    o destination: the destination.
557 %
558 %    o source: the source.
559 %
560 %    o size: the size of the memory in bytes to allocate.
561 %
562 */
563 MagickExport void *CopyMagickMemory(void *destination,const void *source,
564   const size_t size)
565 {
566   register const unsigned char
567     *p;
568
569   register unsigned char
570     *q;
571
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)))
577     switch (size)
578     {
579       default: return(memcpy(destination,source,size));
580       case 8: *q++=(*p++);
581       case 7: *q++=(*p++);
582       case 6: *q++=(*p++);
583       case 5: *q++=(*p++);
584       case 4: *q++=(*p++);
585       case 3: *q++=(*p++);
586       case 2: *q++=(*p++);
587       case 1: *q++=(*p++);
588       case 0: return(destination);
589     }
590   return(memmove(destination,source,size));
591 }
592 \f
593 /*
594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 %                                                                             %
596 %                                                                             %
597 %                                                                             %
598 +   D e s t r o y M a g i c k M e m o r y                                     %
599 %                                                                             %
600 %                                                                             %
601 %                                                                             %
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 %
604 %  DestroyMagickMemory() deallocates memory associated with the memory manager.
605 %
606 %  The format of the DestroyMagickMemory method is:
607 %
608 %      DestroyMagickMemory(void)
609 %
610 */
611 MagickExport void DestroyMagickMemory(void)
612 {
613 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
614   register ssize_t
615     i;
616
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);
625     else
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);
631 #endif
632 }
633 \f
634 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
635 /*
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637 %                                                                             %
638 %                                                                             %
639 %                                                                             %
640 +   E x p a n d H e a p                                                       %
641 %                                                                             %
642 %                                                                             %
643 %                                                                             %
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 %
646 %  ExpandHeap() get more memory from the system.  It returns MagickTrue on
647 %  success otherwise MagickFalse.
648 %
649 %  The format of the ExpandHeap method is:
650 %
651 %      MagickBooleanType ExpandHeap(size_t size)
652 %
653 %  A description of each parameter follows:
654 %
655 %    o size: the size of the memory in bytes we require.
656 %
657 */
658 static MagickBooleanType ExpandHeap(size_t size)
659 {
660   DataSegmentInfo
661     *segment_info;
662
663   MagickBooleanType
664     mapped;
665
666   register ssize_t
667     i;
668
669   register void
670     *block;
671
672   size_t
673     blocksize;
674
675   void
676     *segment;
677
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)
685     return(MagickFalse);
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;
706   return(MagickTrue);
707 }
708 #endif
709 \f
710 /*
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 %                                                                             %
713 %                                                                             %
714 %                                                                             %
715 %   G e t M a g i c k M e m o r y M e t h o d s                               %
716 %                                                                             %
717 %                                                                             %
718 %                                                                             %
719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720 %
721 %  GetMagickMemoryMethods() gets the methods to acquire, resize, and destroy
722 %  memory.
723 %
724 %  The format of the GetMagickMemoryMethods() method is:
725 %
726 %      void GetMagickMemoryMethods(AcquireMemoryHandler *acquire_memory_handler,
727 %        ResizeMemoryHandler *resize_memory_handler,
728 %        DestroyMemoryHandler *destroy_memory_handler)
729 %
730 %  A description of each parameter follows:
731 %
732 %    o acquire_memory_handler: method to acquire memory (e.g. malloc).
733 %
734 %    o resize_memory_handler: method to resize memory (e.g. realloc).
735 %
736 %    o destroy_memory_handler: method to destroy memory (e.g. free).
737 %
738 */
739 MagickExport void GetMagickMemoryMethods(
740   AcquireMemoryHandler *acquire_memory_handler,
741   ResizeMemoryHandler *resize_memory_handler,
742   DestroyMemoryHandler *destroy_memory_handler)
743 {
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;
750 }
751 \f
752 /*
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754 %                                                                             %
755 %                                                                             %
756 %                                                                             %
757 %   G e t M e m o r y I n f o M e m o r y                                     %
758 %                                                                             %
759 %                                                                             %
760 %                                                                             %
761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 %
763 %  GetMemoryInfoMemory() returns a pointer to the allocated memory.
764 %
765 %  The format of the GetMemoryInfoMemory method is:
766 %
767 %      void *GetMemoryInfoMemory(const MemoryInfo *memory_info)
768 %
769 %  A description of each parameter follows:
770 %
771 %    o memory: A pointer to a block of memory to free for reuse.
772 %
773 */
774 MagickExport void *GetMemoryInfoMemory(const MemoryInfo *memory_info)
775 {
776   assert(memory_info != (const MemoryInfo *) NULL);
777   return(memory_info->memory);
778 }
779 \f
780 /*
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 %                                                                             %
783 %                                                                             %
784 %                                                                             %
785 %   R e l i n q u i s h A l i g n e d M e m o r y                             %
786 %                                                                             %
787 %                                                                             %
788 %                                                                             %
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790 %
791 %  RelinquishAlignedMemory() frees memory acquired with AcquireAlignedMemory()
792 %  or reuse.
793 %
794 %  The format of the RelinquishAlignedMemory method is:
795 %
796 %      void *RelinquishAlignedMemory(void *memory)
797 %
798 %  A description of each parameter follows:
799 %
800 %    o memory: A pointer to a block of memory to free for reuse.
801 %
802 */
803 MagickExport void *RelinquishAlignedMemory(void *memory)
804 {
805   if (memory == (void *) NULL)
806     return((void *) NULL);
807 #if defined(MAGICKCORE_HAVE_POSIX_MEMALIGN)
808   free(memory);
809 #elif defined(MAGICKCORE_HAVE__ALIGNED_MALLOC)
810   _aligned_free(memory);
811 #else
812   free(*((void **) memory-1));
813 #endif
814   return(NULL);
815 }
816 \f
817 /*
818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
819 %                                                                             %
820 %                                                                             %
821 %                                                                             %
822 %   R e l i n q u i s h M a g i c k M e m o r y                               %
823 %                                                                             %
824 %                                                                             %
825 %                                                                             %
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827 %
828 %  RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
829 %  or AcquireQuantumMemory() for reuse.
830 %
831 %  The format of the RelinquishMagickMemory method is:
832 %
833 %      void *RelinquishMagickMemory(void *memory)
834 %
835 %  A description of each parameter follows:
836 %
837 %    o memory: A pointer to a block of memory to free for reuse.
838 %
839 */
840 MagickExport void *RelinquishMagickMemory(void *memory)
841 {
842   if (memory == (void *) NULL)
843     return((void *) NULL);
844 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
845   memory_methods.destroy_memory_handler(memory);
846 #else
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)
851     {
852       void
853         *previous;
854
855       /*
856         Coalesce with previous adjacent block.
857       */
858       previous=PreviousBlock(memory);
859       RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
860       *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
861         (*BlockHeader(previous) & ~SizeMask);
862       memory=previous;
863     }
864   if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
865     {
866       void
867         *next;
868
869       /*
870         Coalesce with next adjacent block.
871       */
872       next=NextBlock(memory);
873       RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
874       *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
875         (*BlockHeader(memory) & ~SizeMask);
876     }
877   *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
878   *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
879   InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
880   UnlockSemaphoreInfo(memory_semaphore);
881 #endif
882   return((void *) NULL);
883 }
884 \f
885 /*
886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
887 %                                                                             %
888 %                                                                             %
889 %                                                                             %
890 %   R e l i n q u i s h V i r t u a l M e m o r y                             %
891 %                                                                             %
892 %                                                                             %
893 %                                                                             %
894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 %
896 %  RelinquishMemoryInfo() frees memory acquired with AcquireMemoryInfo()
897 %  or reuse.
898 %
899 %  The format of the RelinquishMemoryInfo method is:
900 %
901 %      void *RelinquishMemoryInfo(const MemoryInfo *memory_info)
902 %
903 %  A description of each parameter follows:
904 %
905 %    o memory_info: A pointer to a block of memory to free for reuse.
906 %
907 */
908 MagickExport MemoryInfo *RelinquishMemoryInfo(const MemoryInfo *memory_info)
909 {
910   return((MemoryInfo *) NULL);
911 }
912 \f
913 /*
914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
915 %                                                                             %
916 %                                                                             %
917 %                                                                             %
918 %   R e s e t M a g i c k M e m o r y                                         %
919 %                                                                             %
920 %                                                                             %
921 %                                                                             %
922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923 %
924 %  ResetMagickMemory() fills the first size bytes of the memory area pointed to
925 %  by memory with the constant byte c.
926 %
927 %  The format of the ResetMagickMemory method is:
928 %
929 %      void *ResetMagickMemory(void *memory,int byte,const size_t size)
930 %
931 %  A description of each parameter follows:
932 %
933 %    o memory: a pointer to a memory allocation.
934 %
935 %    o byte: set the memory to this value.
936 %
937 %    o size: size of the memory to reset.
938 %
939 */
940 MagickExport void *ResetMagickMemory(void *memory,int byte,const size_t size)
941 {
942   assert(memory != (void *) NULL);
943   return(memset(memory,byte,size));
944 }
945 \f
946 /*
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 %                                                                             %
949 %                                                                             %
950 %                                                                             %
951 %   R e s i z e M a g i c k M e m o r y                                       %
952 %                                                                             %
953 %                                                                             %
954 %                                                                             %
955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 %
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.
960 %
961 %  The format of the ResizeMagickMemory method is:
962 %
963 %      void *ResizeMagickMemory(void *memory,const size_t size)
964 %
965 %  A description of each parameter follows:
966 %
967 %    o memory: A pointer to a memory allocation.
968 %
969 %    o size: the new size of the allocated memory.
970 %
971 */
972
973 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
974 static inline void *ResizeBlock(void *block,size_t size)
975 {
976   register void
977     *memory;
978
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);
986   else
987     (void) memcpy(memory,block,SizeOfBlock(block)-sizeof(size_t));
988   memory_pool.allocation+=size;
989   return(memory);
990 }
991 #endif
992
993 MagickExport void *ResizeMagickMemory(void *memory,const size_t size)
994 {
995   register void
996     *block;
997
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);
1004 #else
1005   LockSemaphoreInfo(memory_semaphore);
1006   block=ResizeBlock(memory,size == 0 ? 1UL : size);
1007   if (block == (void *) NULL)
1008     {
1009       if (ExpandHeap(size == 0 ? 1UL : size) == MagickFalse)
1010         {
1011           UnlockSemaphoreInfo(memory_semaphore);
1012           memory=RelinquishMagickMemory(memory);
1013           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1014         }
1015       block=ResizeBlock(memory,size == 0 ? 1UL : size);
1016       assert(block != (void *) NULL);
1017     }
1018   UnlockSemaphoreInfo(memory_semaphore);
1019   memory=RelinquishMagickMemory(memory);
1020 #endif
1021   return(block);
1022 }
1023 \f
1024 /*
1025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026 %                                                                             %
1027 %                                                                             %
1028 %                                                                             %
1029 %   R e s i z e Q u a n t u m M e m o r y                                     %
1030 %                                                                             %
1031 %                                                                             %
1032 %                                                                             %
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034 %
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.
1038 %
1039 %  The format of the ResizeQuantumMemory method is:
1040 %
1041 %      void *ResizeQuantumMemory(void *memory,const size_t count,
1042 %        const size_t quantum)
1043 %
1044 %  A description of each parameter follows:
1045 %
1046 %    o memory: A pointer to a memory allocation.
1047 %
1048 %    o count: the number of quantum elements to allocate.
1049 %
1050 %    o quantum: the number of bytes in each quantum.
1051 %
1052 */
1053 MagickExport void *ResizeQuantumMemory(void *memory,const size_t count,
1054   const size_t quantum)
1055 {
1056   size_t
1057     size;
1058
1059   size=count*quantum;
1060   if ((count == 0) || (quantum != (size/count)))
1061     {
1062       memory=RelinquishMagickMemory(memory);
1063       errno=ENOMEM;
1064       return((void *) NULL);
1065     }
1066   return(ResizeMagickMemory(memory,size));
1067 }
1068 \f
1069 /*
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 %                                                                             %
1072 %                                                                             %
1073 %                                                                             %
1074 %   S e t M a g i c k M e m o r y M e t h o d s                               %
1075 %                                                                             %
1076 %                                                                             %
1077 %                                                                             %
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 %
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.
1083 %
1084 %  The format of the SetMagickMemoryMethods() method is:
1085 %
1086 %      SetMagickMemoryMethods(AcquireMemoryHandler acquire_memory_handler,
1087 %        ResizeMemoryHandler resize_memory_handler,
1088 %        DestroyMemoryHandler destroy_memory_handler)
1089 %
1090 %  A description of each parameter follows:
1091 %
1092 %    o acquire_memory_handler: method to acquire memory (e.g. malloc).
1093 %
1094 %    o resize_memory_handler: method to resize memory (e.g. realloc).
1095 %
1096 %    o destroy_memory_handler: method to destroy memory (e.g. free).
1097 %
1098 */
1099 MagickExport void SetMagickMemoryMethods(
1100   AcquireMemoryHandler acquire_memory_handler,
1101   ResizeMemoryHandler resize_memory_handler,
1102   DestroyMemoryHandler destroy_memory_handler)
1103 {
1104   /*
1105     Set memory methods.
1106   */
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;
1113 }