函数 buf_chunk_init

 http://www.tuicool.com/articles/3QbYfm

 

http://www.360doc.com/content/13/1216/17/12904276_337644353.shtml

buf_chunk_t*结构体见 这里

/********************************************************************//**
Allocates a chunk of buffer frames.
@return    chunk, or NULL on failure */
static
buf_chunk_t*
buf_chunk_init(
/*===========*/
    buf_pool_t*    buf_pool,    /*!< in: buffer pool instance */ //实现
    buf_chunk_t*    chunk,        /*!< out: chunk of buffers */ //实现
    ulint        mem_size)    /*!< in: requested size in bytes */
{
    buf_block_t*    block;
    byte*        frame;
    ulint        i;

    /* Round down to a multiple of page size,
    although it already should be. */
    mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE); //mem_size处理为16K的倍数 /* Reserve space for the block descriptors. */
    mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
                  + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE); //再为block申请内存

    chunk->mem_size = mem_size;
    chunk->mem = os_mem_alloc_large(&chunk->mem_size); //开始申请在内存 if (UNIV_UNLIKELY(chunk->mem == NULL)) {

        return(NULL);
    }

    /* Allocate the block descriptors from the start of the memory block. */
    chunk->blocks = chunk->mem; //结构体描述中说这是一个数组,这里看作是把chunk->mem开始内存地址给他 /* Align a pointer to the first frame.  Note that when
    os_large_page_size is smaller than UNIV_PAGE_SIZE,
    we may allocate one fewer block than requested.  When
    it is bigger, we may allocate more blocks than requested. */

    frame = ut_align(chunk->mem, UNIV_PAGE_SIZE);

/**
*通过while循环,使得第一个frame在最后一个block后面
*/ chunk
->size = chunk->mem_size / UNIV_PAGE_SIZE- (frame != chunk->mem); /* Subtract the space needed for block descriptors. */ { ulint size = chunk->size; /**
*chunk->blocks+size 可理解为构建chunk->blocks数组
*假设size=2000 000 chunk->blocks+2000 000 为 第2000 000个数组的地址
*上面地址肯定大于第一次循环时的frame地址
*
*例如:
*frame = 0x0016 //假设,要与16k对齐
*chunk->blocks = 0x000
*size=2000 000
*第一次循环
*while(0<(byte*)(chunk->blocks+size){
frame=0x0016+16k=0x0032;
size=2000 000 -1=1999 999
}
*第二次循环
*while(0x0032<(byte*)(chunk->blocks+1999 999){
frame=0x0032+16k=0x0048
size=1999 998
}
*依次循环,直到frame大于chunk->block+X size
*此时chunk->size为N个frame

*/
while (frame < (byte*) (chunk->blocks + size)) { frame += UNIV_PAGE_SIZE; size--; } chunk->size = size; } /* Init block structs and assign frames for them. Then we assign the frames to the first blocks (we already mapped the memory above). */ block = chunk->blocks;//是个数组 for (i = chunk->size; i--; ) {
/**
*设置block对应的frame
* block.page的状态为BUF_BLOCK_NOT_USED
*每个block头结构的大小:MySQL 5.1,32位 304 bytes;64位800 bytes
*将mem空间划分为两部分:前部分作为block结构的空间;后部分作为page的空间,
*page空间每一个page的起始位置,必须按照page size对齐       *block结构起始位置,为mem空间的0号位置;       *page空间的起始位置,为预留足够的block结构之后的第一个frame位置

*/ buf_block_init(buf_pool, block, frame); //详见 UNIV_MEM_INVALID(block
->frame, UNIV_PAGE_SIZE); /* Add the block to the free list */ UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page)); //将该block->page放入buf_pool->free双向链表的最后 详见 ut_d(block->page.in_free_list = TRUE); ut_ad(buf_pool_from_block(block) == buf_pool); block++; //block的内存地址+ sizeof(buf_block_t),可理解为数组下一个元素 frame += UNIV_PAGE_SIZE; //下一个frame,可理解为buff_pool中的缓存块 } #ifdef PFS_GROUP_BUFFER_SYNC pfs_register_buffer_block(chunk); #endif return(chunk); }

 

将mem空间划分为两部分:前部分作为block结构的空间;后部分作为

//        page的空间,page空间每一个page的起始位置,必须按照page size对齐

//       block结构起始位置,为mem空间的0号位置;

//        page空间的起始位置,为预留足够的block结构之后的第一个frame位置

你可能感兴趣的:(函数 buf_chunk_init)