__pool<true>::_M_reserve_block
最后,当线程自己的空闲块没有的时候,__mt_alloc必须向内存池的全局空闲块链表求援,于是进入了_M_reserve_block函数。
<mt_allocator.cc>
312 char*
313 __pool<true>::_M_reserve_block(size_t __bytes, const size_t __thread_id)
_M_reserve_block函数原型。返回值是直接给用户使用的块的数据区地址,参数__bytes是用户要求分配的内存的字节大小,__thread_id是分配内存的线程的id。
314 {
315 // Round up to power of 2 and figure out which bin to use.
316 const size_t __which = _M_binmap[__bytes];
317 const _Tune& __options = _M_get_options();
318 const size_t __bin_size = ((__options._M_min_bin << __which)
319 + __options._M_align);
320 size_t __block_count = __options._M_chunk_size - sizeof(_Block_address);
321 __block_count /= __bin_size;
进行一些前期计算,__which是负责分配内存的bin的索引,而__bin_size 是这个bin负责的最大的内存字节数。__options包含当前内存池的一些参数,__block_count表示从OS申请的一块内存(__pool每次总是从OS申请大小为__options._M_chunk_size的内存块)能建造多少个空闲内存块。
322
323 // Are we using threads?
324 // - Yes, check if there are free blocks on the global
325 // list. If so, grab up to __block_count blocks in one
326 // lock and change ownership. If the global list is
327 // empty, we allocate a new chunk and add those blocks
328 // directly to our own freelist (with us as owner).
329 // - No, all operations are made directly to global pool 0
330 // no need to lock or change ownership but check for free
331 // blocks on global list (and if not add new ones) and