| 341 | } |
| 342 | |
| 343 | static void* AllocBlockFrom(int block_type) { |
| 344 | bool locked = false; |
| 345 | if (BAIDU_UNLIKELY(g_dump_enable)) { |
| 346 | g_dump_mutex->lock(); |
| 347 | locked = true; |
| 348 | } |
| 349 | BUTIL_SCOPE_EXIT { |
| 350 | if (locked) { |
| 351 | g_dump_mutex->unlock(); |
| 352 | } |
| 353 | }; |
| 354 | |
| 355 | void* ptr = NULL; |
| 356 | if (0 == block_type && NULL != tls_idle_list) { |
| 357 | CHECK(tls_idle_num > 0); |
| 358 | IdleNode* n = tls_idle_list; |
| 359 | tls_idle_list = n->next; |
| 360 | ptr = n->start; |
| 361 | butil::return_object<IdleNode>(n); |
| 362 | tls_idle_num--; |
| 363 | return ptr; |
| 364 | } |
| 365 | |
| 366 | size_t index = butil::fast_rand() % g_buckets; |
| 367 | BAIDU_SCOPED_LOCK(*g_info->lock[block_type][index]); |
| 368 | IdleNode* node = g_info->idle_list[block_type][index]; |
| 369 | if (NULL == node) { |
| 370 | BAIDU_SCOPED_LOCK(g_info->extend_lock); |
| 371 | node = g_info->idle_list[block_type][index]; |
| 372 | if (NULL == node && NULL != g_info->expansion_list[block_type][index]) { |
| 373 | MoveExpansionList2EmptyIdleList(block_type, index); |
| 374 | node = g_info->idle_list[block_type][index]; |
| 375 | } |
| 376 | if (NULL == node) { |
| 377 | // There is no block left, extend a new region. |
| 378 | if (!ExtendBlockPool(FLAGS_rdma_memory_pool_increase_size_mb, block_type)) { |
| 379 | LOG_EVERY_SECOND(ERROR) << "Fail to extend new region. " |
| 380 | << "You can set the size of memory pool larger. " |
| 381 | << "Refer to the help message of these flags: " |
| 382 | << "rdma_memory_pool_initial_size_mb, " |
| 383 | << "rdma_memory_pool_increase_size_mb, " |
| 384 | << "rdma_memory_pool_max_regions."; |
| 385 | return NULL; |
| 386 | } |
| 387 | MoveExpansionList2EmptyIdleList(block_type, index); |
| 388 | node = g_info->idle_list[block_type][index]; |
| 389 | } |
| 390 | } |
| 391 | CHECK(NULL != node); |
| 392 | |
| 393 | ptr = node->start; |
| 394 | if (node->len > g_block_size[block_type]) { |
| 395 | node->start = (char*)node->start + g_block_size[block_type]; |
| 396 | node->len -= g_block_size[block_type]; |
| 397 | } else { |
| 398 | g_info->idle_list[block_type][index] = node->next; |
| 399 | butil::return_object<IdleNode>(node); |
| 400 | } |
no test coverage detected