| 458 | } |
| 459 | |
| 460 | int DeallocBlock(void* buf) { |
| 461 | if (!buf) { |
| 462 | errno = EINVAL; |
| 463 | return -1; |
| 464 | } |
| 465 | |
| 466 | Region* r = GetRegion(buf); |
| 467 | if (!r) { |
| 468 | errno = ERANGE; |
| 469 | return -1; |
| 470 | } |
| 471 | |
| 472 | IdleNode* node = butil::get_object<IdleNode>(); |
| 473 | if (!node) { |
| 474 | PLOG_EVERY_SECOND(ERROR) << "Memory not enough"; |
| 475 | // May lead to block leak, but do not return -1 |
| 476 | return 0; |
| 477 | } |
| 478 | |
| 479 | uint32_t block_type = r->block_type; |
| 480 | size_t block_size = g_block_size[block_type]; |
| 481 | node->start = buf; |
| 482 | node->len = block_size; |
| 483 | |
| 484 | bool locked = false; |
| 485 | if (BAIDU_UNLIKELY(g_dump_enable)) { |
| 486 | g_dump_mutex->lock(); |
| 487 | locked = true; |
| 488 | } |
| 489 | BUTIL_SCOPE_EXIT { |
| 490 | if (locked) { |
| 491 | g_dump_mutex->unlock(); |
| 492 | } |
| 493 | }; |
| 494 | |
| 495 | if (block_type == 0 && tls_idle_num < (uint32_t)FLAGS_rdma_memory_pool_tls_cache_num) { |
| 496 | if (!tls_inited) { |
| 497 | tls_inited = true; |
| 498 | butil::thread_atexit(RecycleAll); |
| 499 | BAIDU_SCOPED_LOCK(*g_tls_info_mutex); |
| 500 | if (g_tls_info_cnt < 1024) { |
| 501 | g_tls_info[g_tls_info_cnt++] = &tls_idle_num; |
| 502 | } |
| 503 | } |
| 504 | tls_idle_num++; |
| 505 | node->next = tls_idle_list; |
| 506 | tls_idle_list = node; |
| 507 | return 0; |
| 508 | } |
| 509 | |
| 510 | uint64_t index = ((uintptr_t)buf - r->start) * g_buckets / r->size; |
| 511 | if (block_type == 0) { |
| 512 | size_t len = 0; |
| 513 | // Recycle half the cached blocks in tls for default block size |
| 514 | int num = FLAGS_rdma_memory_pool_tls_cache_num / 2; |
| 515 | IdleNode* new_head = tls_idle_list; |
| 516 | IdleNode* recycle_tail = NULL; |
| 517 | for (int i = 0; i < num; ++i) { |