Example #1
0
/**
 * Clear all entries from the memory pool except
 * for @a keep of the given @a size. The pointer
 * returned should be a buffer of @a new_size where
 * the first @a copy_bytes are from @a keep.
 *
 * @param pool memory pool to use for the operation
 * @param keep pointer to the entry to keep (maybe NULL)
 * @param copy_bytes how many bytes need to be kept at this address
 * @param new_size how many bytes should the allocation we return have?
 *                 (should be larger or equal to @a copy_bytes)
 * @return addr new address of @a keep (if it had to change)
 */
void *
MHD_pool_reset (struct MemoryPool *pool,
		void *keep,
		size_t copy_bytes,
                size_t new_size)
{
  if (NULL != keep)
    {
      if (keep != pool->memory)
        {
          memmove (pool->memory,
                   keep,
                   copy_bytes);
          keep = pool->memory;
        }
    }
  pool->end = pool->size;
  /* technically not needed, but safer to zero out */
  memset (&pool->memory[copy_bytes],
	  0,
	  pool->size - copy_bytes);
  if (NULL != keep)
    pool->pos = ROUND_TO_ALIGN (new_size);
  return keep;
}
Example #2
0
/**
 * Clear all entries from the memory pool except
 * for "keep" of the given "size".
 *
 * @param keep pointer to the entry to keep (maybe NULL)
 * @param size how many bytes need to be kept at this address
 * @return addr new address of "keep" (if it had to change)
 */
void *
MHD_pool_reset (struct MemoryPool *pool, 
		void *keep, 
		size_t size)
{
  size = ROUND_TO_ALIGN (size);
  if (keep != NULL)
    {
      if (keep != pool->memory)
        {
          memmove (pool->memory, keep, size);
          keep = pool->memory;
        }
      pool->pos = size;
    }
  pool->end = pool->size;
  return keep;
}
Example #3
0
/**
 * Reallocate a block of memory obtained from the pool.
 * This is particularly efficient when growing or
 * shrinking the block that was last (re)allocated.
 * If the given block is not the most recently
 * (re)allocated block, the memory of the previous
 * allocation may be leaked until the pool is
 * destroyed (and copying the data maybe required).
 *
 * @param pool memory pool to use for the operation
 * @param old the existing block
 * @param old_size the size of the existing block
 * @param new_size the new size of the block
 * @return new address of the block, or
 *         NULL if the pool cannot support @a new_size
 *         bytes (old continues to be valid for @a old_size)
 */
void *
MHD_pool_reallocate (struct MemoryPool *pool,
                     void *old,
		     size_t old_size,
		     size_t new_size)
{
  void *ret;
  size_t asize;

  asize = ROUND_TO_ALIGN (new_size);
  if ( (0 == asize) && (0 != new_size) )
    return NULL; /* new_size too close to SIZE_MAX */
  if ((pool->end < old_size) || (pool->end < asize))
    return NULL;                /* unsatisfiable or bogus request */

  if ( (pool->pos >= old_size) &&
       (&pool->memory[pool->pos - old_size] == old) )
    {
      /* was the previous allocation - optimize! */
      if (pool->pos + asize - old_size <= pool->end)
        {
          /* fits */
          pool->pos += asize - old_size;
          if (asize < old_size)      /* shrinking - zero again! */
            memset (&pool->memory[pool->pos], 0, old_size - asize);
          return old;
        }
      /* does not fit */
      return NULL;
    }
  if (asize <= old_size)
    return old;                 /* cannot shrink, no need to move */
  if ((pool->pos + asize >= pool->pos) &&
      (pool->pos + asize <= pool->end))
    {
      /* fits */
      ret = &pool->memory[pool->pos];
      memmove (ret, old, old_size);
      pool->pos += asize;
      return ret;
    }
  /* does not fit */
  return NULL;
}
Example #4
0
/**
 * Allocate size bytes from the pool.
 * @return NULL if the pool cannot support size more
 *         bytes
 */
void *
MHD_pool_allocate (struct MemoryPool *pool, 
		   size_t size, int from_end)
{
  void *ret;

  size = ROUND_TO_ALIGN (size);
  if ((pool->pos + size > pool->end) || (pool->pos + size < pool->pos))
    return NULL;
  if (from_end == MHD_YES)
    {
      ret = &pool->memory[pool->end - size];
      pool->end -= size;
    }
  else
    {
      ret = &pool->memory[pool->pos];
      pool->pos += size;
    }
  return ret;
}
Example #5
0
/**
 * Allocate size bytes from the pool.
 *
 * @param pool memory pool to use for the operation
 * @param size number of bytes to allocate
 * @param from_end allocate from end of pool (set to #MHD_YES);
 *        use this for small, persistent allocations that
 *        will never be reallocated
 * @return NULL if the pool cannot support size more
 *         bytes
 */
void *
MHD_pool_allocate (struct MemoryPool *pool,
		   size_t size, int from_end)
{
  void *ret;
  size_t asize;

  asize = ROUND_TO_ALIGN (size);
  if ( (0 == asize) && (0 != size) )
    return NULL; /* size too close to SIZE_MAX */
  if ((pool->pos + asize > pool->end) || (pool->pos + asize < pool->pos))
    return NULL;
  if (from_end == MHD_YES)
    {
      ret = &pool->memory[pool->end - asize];
      pool->end -= asize;
    }
  else
    {
      ret = &pool->memory[pool->pos];
      pool->pos += asize;
    }
  return ret;
}