in src/nccl_ofi_freelist.cpp [48:129]
static int freelist_init_internal(size_t entry_size,
size_t initial_entry_count,
size_t increase_entry_count,
size_t max_entry_count,
nccl_ofi_freelist_entry_init_fn entry_init_fn,
nccl_ofi_freelist_entry_fini_fn entry_fini_fn,
bool have_reginfo,
nccl_ofi_freelist_regmr_fn regmr_fn,
nccl_ofi_freelist_deregmr_fn deregmr_fn,
void *regmr_opaque,
size_t entry_alignment,
nccl_ofi_freelist_t **freelist_p)
{
int ret;
nccl_ofi_freelist_t *freelist = NULL;
freelist = (nccl_ofi_freelist_t *)malloc(sizeof(nccl_ofi_freelist_t));
if (!freelist) {
NCCL_OFI_WARN("Allocating freelist failed");
return -ENOMEM;
}
assert(NCCL_OFI_IS_POWER_OF_TWO(entry_alignment));
freelist->memcheck_redzone_size = NCCL_OFI_ROUND_UP(static_cast<size_t>(MEMCHECK_REDZONE_SIZE),
entry_alignment);
/* The rest of the freelist code doesn't deal well with a 0 byte entry
* so increase to 8 bytes in that case rather than adding a bunch of
* special cases for size == 0 in the rest of the code. This happens
* before the bump-up for entry alignment and redzone checking, which
* may further increase the size.
*/
if (entry_size == 0) {
entry_size = 8;
}
freelist->entry_size = NCCL_OFI_ROUND_UP(entry_size,
std::max({entry_alignment, 8ul, MEMCHECK_GRANULARITY}));
freelist->entry_size += freelist->memcheck_redzone_size;
/* Use initial_entry_count and increase_entry_count as lower
* bounds and increase values such that allocations that cover
* full system memory pages do not have unused space for
* additional entries. */
initial_entry_count = freelist_page_padded_entry_count(freelist->entry_size,
initial_entry_count);
increase_entry_count = freelist_page_padded_entry_count(freelist->entry_size,
increase_entry_count);
freelist->num_allocated_entries = 0;
freelist->max_entry_count = max_entry_count;
freelist->increase_entry_count = increase_entry_count;
freelist->entries = NULL;
freelist->blocks = NULL;
freelist->have_reginfo = have_reginfo;
freelist->regmr_fn = regmr_fn;
freelist->deregmr_fn = deregmr_fn;
freelist->regmr_opaque = regmr_opaque;
freelist->entry_init_fn = entry_init_fn;
freelist->entry_fini_fn = entry_fini_fn;
ret = pthread_mutex_init(&freelist->lock, NULL);
if (ret != 0) {
NCCL_OFI_WARN("Mutex initialization failed: %s", strerror(ret));
free(freelist);
return -ret;
}
ret = nccl_ofi_freelist_add(freelist, initial_entry_count);
if (ret != 0) {
NCCL_OFI_WARN("Allocating initial freelist entries failed: %d", ret);
pthread_mutex_destroy(&freelist->lock);
free(freelist);
return ret;
}
*freelist_p = freelist;
return 0;
}