163 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
    Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
 | 
						|
 | 
						|
    Redistribution and use in source and binary forms, with or without
 | 
						|
    modification, are permitted provided that the following conditions
 | 
						|
    are met:
 | 
						|
    1. Redistributions of source code must retain the above copyright
 | 
						|
       notice, this list of conditions and the following disclaimer.
 | 
						|
    2. Redistributions in binary form must reproduce the above copyright
 | 
						|
       notice, this list of conditions and the following disclaimer in the
 | 
						|
       documentation and/or other materials provided with the distribution.
 | 
						|
 | 
						|
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
						|
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
						|
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
						|
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
						|
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
						|
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						|
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						|
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						|
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
						|
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
  tre-mem.c - TRE memory allocator
 | 
						|
 | 
						|
  This software is released under a BSD-style license.
 | 
						|
  See the file LICENSE for details and copyright.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
  This memory allocator is for allocating small memory blocks efficiently
 | 
						|
  in terms of memory overhead and execution speed.  The allocated blocks
 | 
						|
  cannot be freed individually, only all at once.  There can be multiple
 | 
						|
  allocators, though.
 | 
						|
*/
 | 
						|
 | 
						|
#include "tre-prv.h"
 | 
						|
#include "tre-mem.h"
 | 
						|
 | 
						|
 | 
						|
/* Returns a new memory allocator or NULL if out of memory. */
 | 
						|
hawk_tre_mem_t
 | 
						|
hawk_tre_mem_new_impl(hawk_gem_t* gem, int provided, void *provided_block)
 | 
						|
{
 | 
						|
  hawk_tre_mem_t mem;
 | 
						|
  if (provided)
 | 
						|
  {
 | 
						|
      mem = provided_block;
 | 
						|
      HAWK_MEMSET(mem, 0, sizeof(*mem));
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    mem = xcalloc(gem, 1, sizeof(*mem));
 | 
						|
    if (mem == NULL) return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  mem->gem = gem;
 | 
						|
  return mem;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Frees the memory allocator and all memory allocated with it. */
 | 
						|
void
 | 
						|
hawk_tre_mem_destroy(hawk_tre_mem_t mem)
 | 
						|
{
 | 
						|
  hawk_tre_mem_list_t *tmp, *l = mem->blocks;
 | 
						|
 | 
						|
  while (l != NULL)
 | 
						|
    {
 | 
						|
      xfree(mem->gem, l->data);
 | 
						|
      tmp = l->next;
 | 
						|
      xfree(mem->gem, l);
 | 
						|
      l = tmp;
 | 
						|
    }
 | 
						|
  xfree(mem->gem, mem);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
 | 
						|
   allocated block or NULL if an underlying malloc() failed. */
 | 
						|
void *
 | 
						|
hawk_tre_mem_alloc_impl(hawk_tre_mem_t mem, int provided, void *provided_block,
 | 
						|
		   int zero, size_t size)
 | 
						|
{
 | 
						|
  void *ptr;
 | 
						|
 | 
						|
  if (mem->failed)
 | 
						|
    {
 | 
						|
      DPRINT(("tre_mem_alloc: oops, called after failure?!\n"));
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  if (mem->n < size)
 | 
						|
    {
 | 
						|
      /* We need more memory than is available in the current block.
 | 
						|
	 Allocate a new block. */
 | 
						|
      hawk_tre_mem_list_t *l;
 | 
						|
      if (provided)
 | 
						|
	{
 | 
						|
	  DPRINT(("tre_mem_alloc: using provided block\n"));
 | 
						|
	  if (provided_block == NULL)
 | 
						|
	    {
 | 
						|
	      DPRINT(("tre_mem_alloc: provided block was NULL\n"));
 | 
						|
	      mem->failed = 1;
 | 
						|
	      return NULL;
 | 
						|
	    }
 | 
						|
	  mem->ptr = provided_block;
 | 
						|
	  mem->n = TRE_MEM_BLOCK_SIZE;
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	/* HAWK */
 | 
						|
	/*  int block_size;*/
 | 
						|
	  hawk_oow_t block_size;
 | 
						|
	/* END HAWK */
 | 
						|
	  if (size * 8 > TRE_MEM_BLOCK_SIZE)
 | 
						|
	    block_size = size * 8;
 | 
						|
	  else
 | 
						|
	    block_size = TRE_MEM_BLOCK_SIZE;
 | 
						|
	  DPRINT(("tre_mem_alloc: allocating new %lu byte block\n", (unsigned long int)block_size));
 | 
						|
 | 
						|
	  l = xmalloc(mem->gem, sizeof(*l));
 | 
						|
	  if (l == NULL)
 | 
						|
	    {
 | 
						|
	      mem->failed = 1;
 | 
						|
	      return NULL;
 | 
						|
	    }
 | 
						|
	  l->data = xmalloc(mem->gem, block_size);
 | 
						|
	  if (l->data == NULL)
 | 
						|
	    {
 | 
						|
	      xfree(mem->gem, l);
 | 
						|
	      mem->failed = 1;
 | 
						|
	      return NULL;
 | 
						|
	    }
 | 
						|
	  l->next = NULL;
 | 
						|
	  if (mem->current != NULL)
 | 
						|
	    mem->current->next = l;
 | 
						|
	  if (mem->blocks == NULL)
 | 
						|
	    mem->blocks = l;
 | 
						|
	  mem->current = l;
 | 
						|
	  mem->ptr = l->data;
 | 
						|
	  mem->n = block_size;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  /* Make sure the next pointer will be aligned. */
 | 
						|
  size += ALIGN((hawk_uintptr_t)(mem->ptr + size), hawk_uintptr_t);
 | 
						|
 | 
						|
  /* Allocate from current block. */
 | 
						|
  ptr = mem->ptr;
 | 
						|
  mem->ptr += size;
 | 
						|
  mem->n -= size;
 | 
						|
 | 
						|
  /* Set to zero if needed. */
 | 
						|
  if (zero) HAWK_MEMSET(ptr, 0, size);
 | 
						|
  return ptr;
 | 
						|
}
 | 
						|
 | 
						|
/* EOF */
 |