一、第二级配置器 __default_alloc_template 剖析
为了方便管理,SGI第二级配置器会主动将任何小额区块的内存需求量上调至 8 的倍数,并维护 16 个free-lists,各自管理大小分别为 8, 16, 24, 32, 40, 48, 56,64, 72,80,88,96,104,112,120,128 bytes的小额区块。free-lists的节点结构如下:
union obj {
union obj * free_list_link;
char client_data[1]; /* The client sees this. */
};
注意:上述 obj 所用的是 union,由于 union 之故,从其第一字段观之,obj可被视为一个指针,指向相同形式的另一个 obj。从其第二字段观之,obj可被视为一个指针,指向实际区块。
// 以下是第二级配置器
// 注意,无"template型别参数",且第二参数完全没派上用场
// 第一参数用于多线程环境
template <bool threads, int inst>
class __default_alloc_template {
private:
// Really we should use static const int x = N
// instead of enum { x = N }, but few compilers accept the former.
# ifndef __SUNPRO_CC
enum {__ALIGN = 8}; // 小型区块的上调边界
enum {__MAX_BYTES = 128}; // 小型区块的上限
enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; // free-lists 个数
# endif
// ROUND_UP()将 bytes 上调至 8 的倍数
static size_t ROUND_UP(size_t bytes) {
return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1));
}
__PRIVATE:
union obj { // free-lists的节点构造
union obj * free_list_link;
char client_data[1]; /* The client sees this. */
};
private:
# ifdef __SUNPRO_CC
static obj * __VOLATILE free_list[];
// Specifying a size results in duplicate def for 4.1
# else
// 16个free-lists
static obj * __VOLATILE free_list[__NFREELISTS];
# endif
// 以下函数根据区块大小,决定使用第 n 号free-list。n从0起算
static size_t FREELIST_INDEX(size_t bytes) {
return (((bytes) + __ALIGN-1)/__ALIGN - 1);
}
// 返回一个大小为 n 的对象,并可能加入大小为 n 的其他区块到 free list
static void *refill(size_t n);
// 配置一大块空间,可容纳 nobjs 个大小为"size"的区块
// 如果配置 nobjs 个区块有所不便,nobjs可能会降低
static char *chunk_alloc(size_t size, int &nobjs);
// Chunk allocation state.
static char *start_free; // 内存池起始位置。只在 chunk_alloc() 中变化
static char *end_free; // 内存池结束位置。只在