static void *AcquireBlock(size_t size) { register size_t i; register void *block; /* Find free block. */ size=(size_t) (size+sizeof(size_t)+6*sizeof(size_t)-1) & -(4U*sizeof(size_t)); i=AllocationPolicy(size); block=memory_pool.blocks[i]; while ((block != (void *) NULL) && (SizeOfBlock(block) < size)) block=NextBlockInList(block); if (block == (void *) NULL) { i++; while (memory_pool.blocks[i] == (void *) NULL) i++; block=memory_pool.blocks[i]; if (i >= MaxBlocks) return((void *) NULL); } assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0); assert(SizeOfBlock(block) >= size); RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block))); if (SizeOfBlock(block) > size) { size_t blocksize; void *next; /* Split block. */ next=(char *) block+size; blocksize=SizeOfBlock(block)-size; *BlockHeader(next)=blocksize; *BlockFooter(next,blocksize)=blocksize; InsertFreeBlock(next,AllocationPolicy(blocksize)); *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask); } assert(size == SizeOfBlock(block)); *BlockHeader(NextBlock(block))|=PreviousBlockBit; memory_pool.allocation+=size; return(block); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e l i n q u i s h M a g i c k M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory() % or AcquireQuantumMemory() for reuse. % % The format of the RelinquishMagickMemory method is: % % void *RelinquishMagickMemory(void *memory) % % A description of each parameter follows: % % o memory: A pointer to a block of memory to free for reuse. % */ MagickExport void *RelinquishMagickMemory(void *memory) { if (memory == (void *) NULL) return((void *) NULL); #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT) memory_methods.destroy_memory_handler(memory); #else LockSemaphoreInfo(memory_semaphore); assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0); assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0); if ((*BlockHeader(memory) & PreviousBlockBit) == 0) { void *previous; /* Coalesce with previous adjacent block. */ previous=PreviousBlock(memory); RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous))); *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) | (*BlockHeader(previous) & ~SizeMask); memory=previous; } if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0) { void *next; /* Coalesce with next adjacent block. */ next=NextBlock(memory); RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next))); *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) | (*BlockHeader(memory) & ~SizeMask); } *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory); *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit); InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory))); UnlockSemaphoreInfo(memory_semaphore); #endif return((void *) NULL); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e l i n q u i s h M a g i c k M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RelinquishMagickMemory() zeros memory that has been allocated, frees it for % reuse. % % The format of the RelinquishMagickMemory method is: % % void *RelinquishMagickMemory(void *memory) % % A description of each parameter follows: % % o memory: A pointer to a block of memory to free for reuse. % */ MagickExport void *RelinquishMagickMemory(void *memory) { if (memory == (void *) NULL) return((void *) NULL); #if !defined(UseEmbeddableMagick) free(memory); #else assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0); assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0); AcquireSemaphoreInfo(&memory_semaphore); if ((*BlockHeader(memory) & PreviousBlockBit) == 0) { void *previous; /* Coalesce with previous adjacent block. */ previous=PreviousBlock(memory); RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous))); *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) | (*BlockHeader(previous) & ~SizeMask); memory=previous; } if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0) { void *next; /* Coalesce with next adjacent block. */ next=NextBlock(memory); RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next))); *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) | (*BlockHeader(memory) & ~SizeMask); } *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory); *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit); InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory))); RelinquishSemaphoreInfo(memory_semaphore); #endif return((void *) NULL); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + E x p a n d H e a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ExpandHeap() get more memory from the system. It returns MagickTrue on % success otherwise MagickFalse. % % The format of the ExpandHeap method is: % % MagickBooleanType ExpandHeap(size_t size) % % A description of each parameter follows: % % o size: the size of the memory in bytes we require. % */ static MagickBooleanType ExpandHeap(size_t size) { DataSegmentInfo *segment_info; MagickBooleanType mapped; register ssize_t i; register void *block; size_t blocksize; void *segment; blocksize=((size+12*sizeof(size_t))+SegmentSize-1) & -SegmentSize; assert(memory_pool.number_segments < MaxSegments); segment=MapBlob(-1,IOMode,0,blocksize); mapped=segment != (void *) NULL ? MagickTrue : MagickFalse; if (segment == (void *) NULL) segment=(void *) memory_methods.acquire_memory_handler(blocksize); if (segment == (void *) NULL) return(MagickFalse); segment_info=(DataSegmentInfo *) free_segments; free_segments=segment_info->next; segment_info->mapped=mapped; segment_info->length=blocksize; segment_info->allocation=segment; segment_info->bound=(char *) segment+blocksize; i=(ssize_t) memory_pool.number_segments-1; for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--) memory_pool.segments[i+1]=memory_pool.segments[i]; memory_pool.segments[i+1]=segment_info; memory_pool.number_segments++; size=blocksize-12*sizeof(size_t); block=(char *) segment_info->allocation+4*sizeof(size_t); *BlockHeader(block)=size | PreviousBlockBit; *BlockFooter(block,size)=size; InsertFreeBlock(block,AllocationPolicy(size)); block=NextBlock(block); assert(block < segment_info->bound); *BlockHeader(block)=2*sizeof(size_t); *BlockHeader(NextBlock(block))=PreviousBlockBit; return(MagickTrue); }