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

📄 su_alloc.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
	d = d2;      }      if ((n = s->sub_n)) {	for (i = 0; i < n; i++)	  if (s->sub_nodes[i].sua_data) {	    su_block_add(d, s->sub_nodes[i].sua_data)[0] = s->sub_nodes[i];	  }	s->sub_used = 0;	memset(s->sub_nodes, 0, n * sizeof (s->sub_nodes[0]));      }      if (s->sub_stats) {      }    }    UNLOCK(dst); UNLOCK(src);  }  else {    s = MEMLOCK(src);     if (s && s->sub_used) {      s->sub_used = 0;      memset(s->sub_nodes, 0, s->sub_n * sizeof (s->sub_nodes[0]));    }    UNLOCK(src);  }  return 0;}/** Preload a memory home. * * The function su_home_preload() preloads a memory home. */void su_home_preload(su_home_t *home, int n, int isize){  su_block_t *sub;  if (home == NULL)    return;  if (home->suh_blocks == NULL)     su_home_init(home);  sub = MEMLOCK(home);  if (!sub->sub_preload) {    int size;    void *preload;    size = n * ALIGN(isize);    if (size > USHRT_MAX)      size = USHRT_MAX & (ALIGNMENT - 1);    preload = malloc(size);    home->suh_blocks->sub_preload = preload;    home->suh_blocks->sub_prsize = size;  }  UNLOCK(home);}/** Preload a memory home from stack. * * The function su_home_auto() initalizes a memory home using an area * allocated from stack. Poor mans alloca(). */su_home_t *su_home_auto(void *area, int size){  su_home_t *home;  su_block_t *sub;  size_t homesize = ALIGN(sizeof *home);  size_t subsize = ALIGN(offsetof(su_block_t, sub_nodes[SUB_N_AUTO]));  size_t prepsize;  char *p = area;  prepsize = homesize + subsize + (ALIGN((intptr_t)p) - (intptr_t)p);  if (area == NULL || size < prepsize)    return NULL;  home = memset(p, 0, homesize);  home->suh_size = size;  sub = memset(p + homesize, 0, subsize);  home->suh_blocks = sub;  sub->sub_n = SUB_N_AUTO;  sub->sub_preload = p + prepsize;  sub->sub_prsize = size - prepsize;  sub->sub_preauto = 1;  sub->sub_auto = 1;  sub->sub_auto_all = 1;  return home;}/** Reallocate a memory block. * *   The function su_realloc() allocates a memory block of @a size bytes. *   It copies the old block contents to the new block and frees the old *   block. * *   If @a home is NULL, this function behaves exactly like realloc(). * *   @param home  pointer to memory pool object *   @param data  pointer to old memory block *   @param size  size of the memory block to be allocated *    * @return *   This function returns a pointer to the allocated memory block or *   NULL if an error occurred. */void *su_realloc(su_home_t *home, void *data, int size){  void *ndata;  su_alloc_t *sua;  su_block_t *sub;  int p;  int term = -size;  if (!home)     return realloc(data, size);  if (size == 0) {    if (data)      su_free(home, data);    return NULL;  }  sub = MEMLOCK(home);  if (!data) {    data = sub_alloc(home, sub, size, 0);    UNLOCK(home);    return data;  }  sua = su_block_find(sub, data);  if (!su_alloc_check(sub, sua))    return UNLOCK(home);    assert(!sua->sua_home);  if (sua->sua_home)    return UNLOCK(home);    if (!su_is_preloaded(sub, data)) {    ndata = realloc(data, size + MEMCHECK_EXTRA);    if (ndata) {      if (sub->sub_stats) {	su_home_stats_free(sub, data, 0, sua->sua_size);	su_home_stats_alloc(sub, data, 0, size, 1);      }#if MEMCHECK_EXTRA      memcpy((char *)ndata + size, &term, sizeof (term));#else      (void)term;#endif      memset(sua, 0, sizeof *sua);      sub->sub_used--;      su_block_add(sub, ndata)->sua_size = size;    }    UNLOCK(home);    return ndata;  }  p = (char *)data - home->suh_blocks->sub_preload;  p += sua->sua_size + MEMCHECK_EXTRA;  p = ALIGN(p);  if (p == sub->sub_prused) {    int p2 = (char *)data - sub->sub_preload + size + MEMCHECK_EXTRA;    p2 = ALIGN(p2);    if (p2 <= sub->sub_prsize) {      /* Extend/reduce existing preload */      if (sub->sub_stats) {	su_home_stats_free(sub, data, data, sua->sua_size);	su_home_stats_alloc(sub, data, data, size, 0);      }      sub->sub_prused = p2;      sua->sua_size = size;#if MEMCHECK_EXTRA      memcpy((char *)data + size, &term, sizeof (term));#endif      UNLOCK(home);      return data;    }  }  else if (size < sua->sua_size) {    /* Reduce existing preload */    if (sub->sub_stats) {      su_home_stats_free(sub, data, data, sua->sua_size);      su_home_stats_alloc(sub, data, data, size, 0);    }#if MEMCHECK_EXTRA    memcpy((char *)data + size, &term, sizeof (term));#endif    sua->sua_size = size;    UNLOCK(home);    return data;  }  ndata = malloc(size + MEMCHECK_EXTRA);  if (ndata) {    if (p == sub->sub_prused) {      /* Free preload */      sub->sub_prused = (char *)data - home->suh_blocks->sub_preload;      if (sub->sub_stats)	su_home_stats_free(sub, data, data, sua->sua_size);    }        memcpy(ndata, data, sua->sua_size < size ? sua->sua_size : size);#if MEMCHECK_EXTRA    memcpy((char *)ndata + size, &term, sizeof (term));#endif    if (sub->sub_stats)      su_home_stats_alloc(sub, data, 0, size, 1);    memset(sua, 0, sizeof *sua); sub->sub_used--;    su_block_add(sub, ndata)->sua_size = size;  }  UNLOCK(home);  return ndata;}/**Allocate and zero a memory block. * * The function su_zalloc() allocates a memory block with a given size from * given memory home @a home and zeroes the allocated block. * *  @param home  pointer to memory pool object *  @param size  size of the memory block * * @note The memory home pointer @a home may be @c NULL. In that case, the * allocated memory block is not associated with any memory home, and it * must be freed by calling su_free() or free(). * * @return * The function su_zalloc() returns a pointer to the allocated memory block, * or NULL upon an error. */void *su_zalloc(su_home_t *home, int  size){  void *data;  assert (size >= 0);  if (home) {    data = sub_alloc(home, MEMLOCK(home), size, 1);    UNLOCK(home);  }  else    data = calloc(1, size);  return data;}/** Allocate a structure * * The function su_salloc() allocates a structure with a given size, zeros * it, and initializes the size field to the given size.  The size field * is the first in the structure. * * @param home  pointer to memory pool object * @param size  size of the structure * * @par Example * The structure is defined and allocated as follows: * @code *   struct test { *     int   tst_size; *     char *tst_name; *     void *tst_ptr[3]; *   }; *  *   struct test *t; *   ... *   t = su_salloc(home, sizeof (*t));  *   assert(t && t->t_size == sizeof (*t)); *   t->name * @endcode * After calling su_salloc() we get a pointer t to a struct test, * initialized to zero except the  * * * @return This function returns a pointer to the allocated structure, or * NULL upon an error. */void *su_salloc(su_home_t *home, int size){  struct { int size; } *retval;  if (size < sizeof (*retval))    size = sizeof (*retval);  assert (size >= 0);  if (home) {    retval = sub_alloc(home, MEMLOCK(home), size, 1);    UNLOCK(home);  }  else    retval = calloc(1, size);  if (retval)    retval->size = size;  return retval;}/** Check if a memory home is threadsafe */int su_home_is_threadsafe(su_home_t const *home){  return home && home->suh_lock;}/** Obtain exclusive lock on home (if home is threadsafe). */int su_home_mutex_lock(su_home_t *home){  if (home == NULL)    return su_seterrno(EFAULT);  if (home->suh_lock) {    su_home_ref(home);    su_home_mutex_locker(home->suh_lock);  }  else if (home->suh_blocks) {    if (!su_home_ref(home))      return -1;  }  return 0;}/** Release exclusive lock on home (if home is threadsafe) */int su_home_mutex_unlock(su_home_t *home){  if (home == NULL)    return su_seterrno(EFAULT);  if (home->suh_lock) {    su_home_mutex_unlocker(home->suh_lock);    su_home_unref(home);  }  else if (home->suh_blocks) {    su_home_unref(home);  }  return 0;}/** Initialize statistics structure */void su_home_init_stats(su_home_t *home){  su_block_t *sub;  int size;  if (home == NULL)    return;  sub = home->suh_blocks;  if (!sub)    sub = home->suh_blocks = su_hash_alloc(SUB_N);  if (!sub)    return;  if (!sub->sub_stats) {    size = sizeof (*sub->sub_stats);    sub->sub_stats = malloc(size);    if (!sub->sub_stats)      return;  }  else    size = sub->sub_stats->hs_size;    memset(sub->sub_stats, 0, size);  sub->sub_stats->hs_size = size;  sub->sub_stats->hs_blocksize = sub->sub_n;}/** Retrieve statistics from memory home. */void su_home_get_stats(su_home_t *home, int include_clones, 		       su_home_stat_t hs[1],		       int size){  su_block_t *sub;  if (hs == NULL || size < (sizeof hs->hs_size))    return;  memset(hs, 0, size);  sub = MEMLOCK(home);  if (sub && sub->sub_stats) {    int sub_size = sub->sub_stats->hs_size;    if (sub_size > size)      sub_size = size;    sub->sub_stats->hs_preload.hsp_size = sub->sub_prsize;    sub->sub_stats->hs_preload.hsp_used = sub->sub_prused;    memcpy(hs, sub->sub_stats, sub_size);    hs->hs_size = size;  }  UNLOCK(home);}static void su_home_stats_alloc(su_block_t *sub, void *p, void *preload,			 unsigned size, int zero){  su_home_stat_t *hs = sub->sub_stats;  unsigned rsize = ALIGN(size);  hs->hs_rehash += (sub->sub_n != hs->hs_blocksize);  hs->hs_blocksize = sub->sub_n;  hs->hs_clones += zero > 1;  if (preload) {    hs->hs_allocs.hsa_preload++;    return;  }  hs->hs_allocs.hsa_number++;  hs->hs_allocs.hsa_bytes += size;  hs->hs_allocs.hsa_rbytes += rsize;  if (hs->hs_allocs.hsa_rbytes > hs->hs_allocs.hsa_maxrbytes)    hs->hs_allocs.hsa_maxrbytes = hs->hs_allocs.hsa_rbytes;    hs->hs_blocks.hsb_number++;  hs->hs_blocks.hsb_bytes += size;  hs->hs_blocks.hsb_rbytes += rsize;}static void su_home_stats_free(su_block_t *sub, void *p, void *preload, unsigned size){  su_home_stat_t *hs = sub->sub_stats;  unsigned rsize = ALIGN(size);  if (preload) {    hs->hs_frees.hsf_preload++;    return;  }  hs->hs_frees.hsf_number++;  hs->hs_frees.hsf_bytes += size;  hs->hs_frees.hsf_rbytes += rsize;  hs->hs_blocks.hsb_number--;  hs->hs_blocks.hsb_bytes -= size;  hs->hs_blocks.hsb_rbytes -= rsize;}void su_home_stat_add(su_home_stat_t total[1], su_home_stat_t const hs[1]){  total->hs_clones               += hs->hs_clones;  total->hs_rehash               += hs->hs_rehash;  if (total->hs_blocksize < hs->hs_blocksize)    total->hs_blocksize = hs->hs_blocksize;  total->hs_allocs.hsa_number    += hs->hs_allocs.hsa_number;  total->hs_allocs.hsa_bytes     += hs->hs_allocs.hsa_bytes;  total->hs_allocs.hsa_rbytes    += hs->hs_allocs.hsa_rbytes;  total->hs_allocs.hsa_maxrbytes += hs->hs_allocs.hsa_maxrbytes;  total->hs_frees.hsf_number     += hs->hs_frees.hsf_number;  total->hs_frees.hsf_bytes      += hs->hs_frees.hsf_bytes;  total->hs_frees.hsf_rbytes     += hs->hs_frees.hsf_rbytes;  total->hs_blocks.hsb_number    += hs->hs_blocks.hsb_number;  total->hs_blocks.hsb_bytes     += hs->hs_blocks.hsb_bytes;  total->hs_blocks.hsb_rbytes    += hs->hs_blocks.hsb_rbytes;}

⌨️ 快捷键说明

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