apache1.3.39源码alloc.c阅览笔记

apache1.3.39源码alloc.c阅读笔记

apache1.3.39源码alloc.c阅读笔记

2011年06月03日

  typedef struct pool pool;   内存块管理API

  malloc_block

  从系统申请sizeof(block_hdr)+size大小的内存

  blok->h.first_avail=(char *)(blok+1);

  blok->h.endp = size + blok->h.first_avail;

  free_blocks

  将一条内存块链加到block_freelist链表开头,该过程会将该链表中所有的h.first_avail置为内存块开头即 (char *)(blok + 1)。

  new_block

  申请一块内存块,先从block_freelist中找,线性查找,找到第一个满足h.endp-h.first_avail>size+MINFREE条件的返回,并从freelist中去掉,否则调用malloc_block从系统申请,申请的时候也有最小块限制MINALLOC

  bytes_in_block_list

  返回某个内存块链的总长度(不是可用长度,而是总长度)

  pool管理,pool分配大小对齐于align结构体的倍数

  #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) – 1) / CLICK_SZ))

  #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)

  API

  ap_block_alarms

  ap_unblock_alarms

  包装。。临界区?

  pool *ap_make_sub_pool(pool *)

  创建一个子pool,参数为NULL的时候无父pool,父pool.sub_pools是一个双向链表,新的子pool加入到链表头,free_first_avail指向第一个blok分配了pool结构体之后的内存。

  ap_init_alloc

  分配全局的父pool static pool *permanent_pool;

  void ap_cleanup_alloc(void)

  do nothing

  ap_clear_pool && ap_destroy_pool

  从最底层的子pool开始,调用

  run_cleanups(a->cleanups)

  free_proc_chain(a->subprocesses);

  free_blocks(a->first->h.next);

  destroy会把含有pool结构体的block也free掉

  free_blocks(a->first);

  clear会保留这个结构体所在的block,其他的free掉

  总体逻辑

  destroy(a)的过程,先clear(a),然后如果a有父pool,那么修改a的父pool的sub_pools链表,以及a自身的sub_pre,sub_next,将a从子pool链中移除。

  clear(a)的过程,先destroy掉a的所有子pool,然后调用a的

  run_cleanups(a->cleanups);

  free_proc_chain(a->subprocesses);

  free_blocks(a->first->h.next);

  像一个双函数递归过程。

  其中

  enum kill_conditions {

  kill_never,         /* process is never sent any signals */

  kill_always,        /* process is sent SIGKILL on pool cleanup */

  kill_after_timeout,     /* SIGTERM, wait 3 seconds, SIGKILL */

  just_wait,          /* wait forever for the process to complete */

  kill_only_once      /* send SIGTERM and then wait */

  };

  内存分配api

  API_EXPORT(void *) ap_palloc(struct pool *a, int reqsize)

  先在pool的最后一个block上找,可用空间是否够,不够就申请一块新的block挂在pool的block链表之后

  API_EXPORT(void *) ap_pcalloc(struct pool *a, int size)

  调用上述函数之后,调用memset将内存设置为0

  API_EXPORT(char *) ap_pstrdup(struct pool *a, const char *s)

  在pool上分配strlen(a)+1内存后,把字符串a memcpy 过去

  API_EXPORT(char *) ap_pstrndup(struct pool *a, const char *s, int n)

  在pool上分配n+1大小的内存,然后从a中memcpy n个字符过去,最后补0

  API_EXPORT_NONSTD(char *) ap_pstrcat(pool *a,…)

  在pool上分配字符串总长度+1大小的内存,然后把各个字符串cat成一个。

  apache格式化输出API

  内部函数

  static int psprintf_flush(ap_vformatter_buff *vbuff)

  自动扩展vbuff,若空间不足则申请新的block并free掉旧的

  static char *conv_10(register wide_int num, register bool_int is_unsigned,register bool_int *is_negative, char *buf_end,register int *len)

  转换成十进制字符串,从右往左转换,返回开头指针

  调用的时候buf_end给的是&num_buf[NUM_BUF_SIZE],没有判断越界,NUM_BUF_SIZE=512,加上精度和’\0’一共最多512个字符

  static char *conv_p2(register u_wide_int num, register int nbits,char format, char *buf_end, register int *len)

  转换成2的nbits次方进制字符串

  register int mask = (1 >= nbits;

  }

  while (num);

  static char *conv_fp(register char format, register double num,boolean_e add_dp, int precision, bool_int *is_negative,char *buf, int *len)

  根据format为f,e,E,将num转化为字符串

  static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len)

  转化成IP:PORT字符串

  %pI %pA

  API_EXPORT(char *) ap_pvsprintf(pool *p, const char *fmt, va_list ap)

  pool接口的vsprintf函数

apache1.3.39源码alloc.c阅览笔记

相关文章:

你感兴趣的文章:

标签云: