⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpool.c

📁 一个关于memory pool 的实例
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* free the memory */    ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p));    if (ret != MPOOL_ERROR_NONE) {      final = ret;    }  }    return final;}/* * void *mpool_alloc * * DESCRIPTION: * * Allocate space for bytes inside of an already open memory pool. * * RETURNS: * * Success - Pointer to the address to use. * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool.  If NULL then it will do a * normal malloc. * * byte_size -> Number of bytes to allocate in the pool.  Must be >0. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */void	*mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,		     int *error_p){  void	*addr;    if (mp_p == NULL) {    /* special case -- do a normal malloc */    addr = (void *)malloc(byte_size);    if (addr == NULL) {      SET_POINTER(error_p, MPOOL_ERROR_ALLOC);      return NULL;    }    else {      SET_POINTER(error_p, MPOOL_ERROR_NONE);      return addr;    }  }    if (mp_p->mp_magic != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_PNT);    return NULL;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);    return NULL;  }    if (byte_size == 0) {    SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);    return NULL;  }    addr = alloc_mem(mp_p, byte_size, error_p);    if (mp_p->mp_log_func != NULL) {    mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, addr, NULL, 0);  }    return addr;}/* * void *mpool_calloc * * DESCRIPTION: * * Allocate space for elements of bytes in the memory pool and zero * the space afterwards. * * RETURNS: * * Success - Pointer to the address to use. * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool.  If NULL then it will do a * normal calloc. * * ele_n -> Number of elements to allocate. * * ele_size -> Number of bytes per element being allocated. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */void	*mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,		      const unsigned long ele_size, int *error_p){  void		*addr;  unsigned long	byte_size;    if (mp_p == NULL) {    /* special case -- do a normal calloc */    addr = (void *)calloc(ele_n, ele_size);    if (addr == NULL) {      SET_POINTER(error_p, MPOOL_ERROR_ALLOC);      return NULL;    }     else {      SET_POINTER(error_p, MPOOL_ERROR_NONE);      return addr;    }  }  if (mp_p->mp_magic != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_PNT);    return NULL;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);    return NULL;  }    if (ele_n == 0 || ele_size == 0) {    SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);    return NULL;  }    byte_size = ele_n * ele_size;  addr = alloc_mem(mp_p, byte_size, error_p);  if (addr != NULL) {    memset(addr, 0, byte_size);  }    if (mp_p->mp_log_func != NULL) {    mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, addr, NULL, 0);  }    /* NOTE: error_p set above */  return addr;}/* * int mpool_free * * DESCRIPTION: * * Free an address from a memory pool. * * RETURNS: * * Success - MPOOL_ERROR_NONE * * Failure - Mpool error code * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool.  If NULL then it will do a * normal free. * * addr <-> Address to free. * * size -> Size of the address being freed. */int	mpool_free(mpool_t *mp_p, void *addr, const unsigned long size){  if (mp_p == NULL) {    /* special case -- do a normal free */    free(addr);    return MPOOL_ERROR_NONE;  }  if (mp_p->mp_magic != MPOOL_MAGIC) {    return MPOOL_ERROR_PNT;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    return MPOOL_ERROR_POOL_OVER;  }    if (mp_p->mp_log_func != NULL) {    mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, size, 0, NULL, addr, 0);  }    if (addr == NULL) {    return MPOOL_ERROR_ARG_NULL;  }  if (size == 0) {    return MPOOL_ERROR_ARG_INVALID;  }    return free_mem(mp_p, addr, size);}/* * void *mpool_resize * * DESCRIPTION: * * Reallocate an address in a mmeory pool to a new size.  This is * different from realloc in that it needs the old address' size.  If * you don't have it then you need to allocate new space, copy the * data, and free the old pointer yourself. * * RETURNS: * * Success - Pointer to the address to use. * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool.  If NULL then it will do a * normal realloc. * * old_addr -> Previously allocated address. * * old_byte_size -> Size of the old address.  Must be known, cannot be * 0. * * new_byte_size -> New size of the allocation. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */void	*mpool_resize(mpool_t *mp_p, void *old_addr,		      const unsigned long old_byte_size,		      const unsigned long new_byte_size,		      int *error_p){  unsigned long	copy_size, new_size, old_size, fence;  void		*new_addr;  mpool_block_t	*block_p;  int		ret;    if (mp_p == NULL) {    /* special case -- do a normal realloc */    new_addr = (void *)realloc(old_addr, new_byte_size);    if (new_addr == NULL) {      SET_POINTER(error_p, MPOOL_ERROR_ALLOC);      return NULL;    }     else {      SET_POINTER(error_p, MPOOL_ERROR_NONE);      return new_addr;    }  }    if (mp_p->mp_magic != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_PNT);    return NULL;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);    return NULL;  }    if (old_addr == NULL) {    SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL);    return NULL;  }  if (old_byte_size == 0) {    SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);    return NULL;  }    /*   * If the size is larger than a block then the allocation must be at   * the front of the block.   */  if (old_byte_size > MAX_BLOCK_USER_MEMORY(mp_p)) {    block_p = (mpool_block_t *)((char *)old_addr - sizeof(mpool_block_t));    if (block_p->mb_magic != BLOCK_MAGIC	|| block_p->mb_magic2 != BLOCK_MAGIC) {      SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);      return NULL;    }  }    /* make sure we have enough bytes */  if (old_byte_size < MIN_ALLOCATION) {    old_size = MIN_ALLOCATION;  }  else {    old_size = old_byte_size;  }    /* verify that the size matches exactly if we can */  if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {    fence = 0;  }  else if (old_size > 0) {    ret = check_magic(old_addr, old_size);    if (ret != MPOOL_ERROR_NONE) {      SET_POINTER(error_p, ret);      return NULL;    }    fence = FENCE_SIZE;  }    /* make sure we have enough bytes */  if (new_byte_size < MIN_ALLOCATION) {    new_size = MIN_ALLOCATION;  }  else {    new_size = new_byte_size;  }    /*   * NOTE: we could here see if the size is the same or less and then   * use the current memory and free the space above.  This is harder   * than it sounds if we are changing the block size of the   * allocation.   */    /* we need to get another address */  new_addr = alloc_mem(mp_p, new_byte_size, error_p);  if (new_addr == NULL) {    /* error_p set in mpool_alloc */    return NULL;  }    if (new_byte_size > old_byte_size) {    copy_size = old_byte_size;  }  else {    copy_size = new_byte_size;  }  memcpy(new_addr, old_addr, copy_size);    /* free the old address */  ret = free_mem(mp_p, old_addr, old_byte_size);  if (ret != MPOOL_ERROR_NONE) {    /* if the old free failed, try and free the new address */    (void)free_mem(mp_p, new_addr, new_byte_size);    SET_POINTER(error_p, ret);    return NULL;  }    if (mp_p->mp_log_func != NULL) {    mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size,		      0, new_addr, old_addr, old_byte_size);  }    SET_POINTER(error_p, MPOOL_ERROR_NONE);  return new_addr;}/* * int mpool_stats * * DESCRIPTION: * * Return stats from the memory pool. * * RETURNS: * * Success - MPOOL_ERROR_NONE * * Failure - Mpool error code * * ARGUMENTS: * * mp_p -> Pointer to the memory pool. * * page_size_p <- Pointer to an unsigned integer which, if not NULL, * will be set to the page-size of the pool. * * num_alloced_p <- Pointer to an unsigned long which, if not NULL, * will be set to the number of pointers currently allocated in pool. * * user_alloced_p <- Pointer to an unsigned long which, if not NULL, * will be set to the number of user bytes allocated in this pool. * * max_alloced_p <- Pointer to an unsigned long which, if not NULL, * will be set to the maximum number of user bytes that have been * allocated in this pool. * * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, * will be set to the total amount of space (including administrative * overhead) used by the pool. */int	mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,		    unsigned long *num_alloced_p,		    unsigned long *user_alloced_p,		    unsigned long *max_alloced_p,		    unsigned long *tot_alloced_p){  if (mp_p == NULL) {    return MPOOL_ERROR_ARG_NULL;  }  if (mp_p->mp_magic != MPOOL_MAGIC) {    return MPOOL_ERROR_PNT;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    return MPOOL_ERROR_POOL_OVER;  }    SET_POINTER(page_size_p, mp_p->mp_page_size);  SET_POINTER(num_alloced_p, mp_p->mp_alloc_c);  SET_POINTER(user_alloced_p, mp_p->mp_user_alloc);  SET_POINTER(max_alloced_p, mp_p->mp_max_alloc);  SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c));    return MPOOL_ERROR_NONE;}/* * int mpool_set_log_func * * DESCRIPTION: * * Set a logging callback function to be called whenever there was a * memory transaction.  See mpool_log_func_t. * * RETURNS: * * Success - MPOOL_ERROR_NONE * * Failure - Mpool error code * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool. * * log_func -> Log function (defined in mpool.h) which will be called * with each mpool transaction. */int	mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func){  if (mp_p == NULL) {    return MPOOL_ERROR_ARG_NULL;  }  if (mp_p->mp_magic != MPOOL_MAGIC) {    return MPOOL_ERROR_PNT;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    return MPOOL_ERROR_POOL_OVER;  }    mp_p->mp_log_func = log_func;    return MPOOL_ERROR_NONE;}/* * int mpool_set_max_pages * * DESCRIPTION: * * Set the maximum number of pages that the library will use.  Once it * hits the limit it will return MPOOL_ERROR_NO_PAGES. * * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages * value will include the page with the mpool header structure in it. * If the flag is _not_ set then the max-pages will not include this * first page. * * RETURNS: * * Success - MPOOL_ERROR_NONE * * Failure - Mpool error code * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool. * * max_pages -> Maximum number of pages used by the library. */int	mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages){  if (mp_p == NULL) {    return MPOOL_ERROR_ARG_NULL;  }  if (mp_p->mp_magic != MPOOL_MAGIC) {    return MPOOL_ERROR_PNT;  }  if (mp_p->mp_magic2 != MPOOL_MAGIC) {    return MPOOL_ERROR_POOL_OVER;  }    if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) {    mp_p->mp_max_pages = max_pages;  }  else {    /*     * If we are not heavy-packing the pool then we don't count the     * 1st page allocated which holds the mpool header structure.     */    mp_p->mp_max_pages = max_pages + 1;  }    return MPOOL_ERROR_NONE;}/* * const char *mpool_strerror * * DESCRIPTION: * * Return the corresponding string for the error number. * * RETURNS: * * Success - String equivalient of the error. * * Failure - String "invalid error code" * * ARGUMENTS: * * error -> Error number that we are converting. */const char	*mpool_strerror(const int error){  switch (error) {  case MPOOL_ERROR_NONE:    return "no error";    break;  case MPOOL_ERROR_ARG_NULL:    return "function argument is null";    break;  case MPOOL_ERROR_ARG_INVALID:    return "function argument is invalid";    break;  case MPOOL_ERROR_PNT:    return "invalid mpool pointer";    break;  case MPOOL_ERROR_POOL_OVER:    return "mpool structure was overwritten";    break;  case MPOOL_ERROR_PAGE_SIZE:    return "could not get system page-size";    break;  case MPOOL_ERROR_OPEN_ZERO:    return "could not open /dev/zero";    break;  case MPOOL_ERROR_NO_MEM:    return "no memory available";    break;  case MPOOL_ERROR_MMAP:    return "problems with mmap";    break;  case MPOOL_ERROR_SIZE:    return "error processing requested size";    break;  case MPOOL_ERROR_TOO_BIG:    return "allocation exceeds pool max size";    break;  case MPOOL_ERROR_MEM:    return "invalid memory address";    break;  case MPOOL_ERROR_MEM_OVER:    return "memory lower bounds overwritten";    break;  case MPOOL_ERROR_NOT_FOUND:    return "memory block not found in pool";    break;  case MPOOL_ERROR_IS_FREE:    return "memory address has already been freed";    break;  case MPOOL_ERROR_BLOCK_STAT:    return "invalid internal block status";    break;  case MPOOL_ERROR_FREE_ADDR:    return "invalid internal free address";    break;  case MPOOL_ERROR_SBRK_CONTIG:    return "sbrk did not return contiguous memory";    break;  case MPOOL_ERROR_NO_PAGES:    return "no available pages left in pool";    break;  case MPOOL_ERROR_ALLOC:    return "system alloc function failed";    break;  case MPOOL_ERROR_PNT_OVER:    return "user pointer admin space overwritten";    break;  default:    break;  }    return "invalid error code";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -