| 131 | } |
| 132 | |
| 133 | static void* ExtendBlockPoolImpl(void* region_base, size_t region_size, int block_type) { |
| 134 | auto region_base_guard = butil::MakeScopeGuard([region_base]() { |
| 135 | free(region_base); |
| 136 | }); |
| 137 | |
| 138 | if (g_region_num == FLAGS_rdma_memory_pool_max_regions) { |
| 139 | LOG_EVERY_SECOND(ERROR) << "Memory pool reaches max regions"; |
| 140 | errno = ENOMEM; |
| 141 | return NULL; |
| 142 | } |
| 143 | |
| 144 | uint32_t id = g_cb(region_base, region_size); |
| 145 | if (id == 0) { |
| 146 | errno = EINVAL; |
| 147 | return NULL; |
| 148 | } |
| 149 | |
| 150 | IdleNode* node[g_buckets]; |
| 151 | for (size_t i = 0; i < g_buckets; ++i) { |
| 152 | node[i] = butil::get_object<IdleNode>(); |
| 153 | if (!node[i]) { |
| 154 | PLOG_EVERY_SECOND(ERROR) << "Memory not enough"; |
| 155 | for (size_t j = 0; j < i; ++j) { |
| 156 | butil::return_object<IdleNode>(node[j]); |
| 157 | } |
| 158 | errno = ENOMEM; |
| 159 | return NULL; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | Region* region = &g_regions[g_region_num++]; |
| 164 | region->start = (uintptr_t)region_base; |
| 165 | region->size = region_size; |
| 166 | region->id = id; |
| 167 | region->block_type = block_type; |
| 168 | |
| 169 | for (size_t i = 0; i < g_buckets; ++i) { |
| 170 | node[i]->start = (void*)(region->start + i * (region_size / g_buckets)); |
| 171 | node[i]->len = region_size / g_buckets; |
| 172 | node[i]->next = g_info->expansion_list[block_type][i]; |
| 173 | g_info->expansion_list[block_type][i] = node[i]; |
| 174 | g_info->expansion_size[block_type][i] += node[i]->len; |
| 175 | } |
| 176 | g_info->region_num[block_type]++; |
| 177 | |
| 178 | // `region_base' is inuse, cannot be freed. |
| 179 | region_base_guard.dismiss(); |
| 180 | |
| 181 | return region_base; |
| 182 | } |
| 183 | |
| 184 | // Extend the block pool with a new region (with different region ID) |
| 185 | static void* ExtendBlockPool(size_t region_size, int block_type) { |
no test coverage detected