Skip to content

Commit

Permalink
Merge pull request #770 from ldorau/Implement_more_API_of_the_Coarse_…
Browse files Browse the repository at this point in the history
…provider

Implement split()/merge() API of the Coarse provider
  • Loading branch information
lplewa authored Oct 10, 2024
2 parents 9fc6aa3 + 3a5b33c commit 0ba0b97
Show file tree
Hide file tree
Showing 2 changed files with 392 additions and 6 deletions.
190 changes: 184 additions & 6 deletions src/provider/provider_coarse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ static umf_result_t coarse_memory_provider_alloc(void *provider, size_t size,
(struct coarse_memory_provider_t *)provider;

if (utils_mutex_lock(&coarse_provider->lock) != 0) {
LOG_ERR("lockng the lock failed");
LOG_ERR("locking the lock failed");
return UMF_RESULT_ERROR_UNKNOWN;
}

Expand Down Expand Up @@ -1329,7 +1329,7 @@ static umf_result_t coarse_memory_provider_free(void *provider, void *ptr,
(struct coarse_memory_provider_t *)provider;

if (utils_mutex_lock(&coarse_provider->lock) != 0) {
LOG_ERR("lockng the lock failed");
LOG_ERR("locking the lock failed");
return UMF_RESULT_ERROR_UNKNOWN;
}

Expand All @@ -1351,7 +1351,12 @@ static umf_result_t coarse_memory_provider_free(void *provider, void *ptr,
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

assert(bytes == 0 || bytes == block->size);
if (bytes > 0 && bytes != block->size) {
// wrong size of allocation
utils_mutex_unlock(&coarse_provider->lock);
LOG_ERR("wrong size of allocation");
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

LOG_DEBUG("coarse_FREE (return_block_to_pool) %zu used %zu alloc %zu",
block->size, coarse_provider->used_size - block->size,
Expand Down Expand Up @@ -1511,6 +1516,179 @@ coarse_memory_provider_get_stats(void *provider,
return UMF_RESULT_SUCCESS;
}

static umf_result_t coarse_memory_provider_allocation_split(void *provider,
void *ptr,
size_t totalSize,
size_t firstSize) {
if (provider == NULL || ptr == NULL || (firstSize >= totalSize) ||
firstSize == 0) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

umf_result_t umf_result;

coarse_memory_provider_t *coarse_provider =
(struct coarse_memory_provider_t *)provider;

if (utils_mutex_lock(&coarse_provider->lock) != 0) {
LOG_ERR("locking the lock failed");
return UMF_RESULT_ERROR_UNKNOWN;
}

assert(debug_check(coarse_provider));

ravl_node_t *node = coarse_ravl_find_node(coarse_provider->all_blocks, ptr);
if (node == NULL) {
LOG_ERR("memory block not found");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

block_t *block = get_node_block(node);

if (block->size != totalSize) {
LOG_ERR("wrong totalSize");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

if (!block->used) {
LOG_ERR("block is not allocated");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

block_t *new_block = coarse_ravl_add_new(coarse_provider->all_blocks,
block->data + firstSize,
block->size - firstSize, NULL);
if (new_block == NULL) {
umf_result = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
goto err_mutex_unlock;
}

block->size = firstSize;
new_block->used = true;

assert(new_block->size == (totalSize - firstSize));

umf_result = UMF_RESULT_SUCCESS;

err_mutex_unlock:
assert(debug_check(coarse_provider));

if (utils_mutex_unlock(&coarse_provider->lock) != 0) {
LOG_ERR("unlocking the lock failed");
if (umf_result == UMF_RESULT_SUCCESS) {
umf_result = UMF_RESULT_ERROR_UNKNOWN;
}
}

return umf_result;
}

static umf_result_t coarse_memory_provider_allocation_merge(void *provider,
void *lowPtr,
void *highPtr,
size_t totalSize) {
if (provider == NULL || lowPtr == NULL || highPtr == NULL ||
((uintptr_t)highPtr <= (uintptr_t)lowPtr) ||
((uintptr_t)highPtr - (uintptr_t)lowPtr >= totalSize)) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

umf_result_t umf_result;

coarse_memory_provider_t *coarse_provider =
(struct coarse_memory_provider_t *)provider;

if (utils_mutex_lock(&coarse_provider->lock) != 0) {
LOG_ERR("locking the lock failed");
return UMF_RESULT_ERROR_UNKNOWN;
}

assert(debug_check(coarse_provider));

ravl_node_t *low_node =
coarse_ravl_find_node(coarse_provider->all_blocks, lowPtr);
if (low_node == NULL) {
LOG_ERR("the lowPtr memory block not found");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

block_t *low_block = get_node_block(low_node);
if (!low_block->used) {
LOG_ERR("the lowPtr block is not allocated");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

ravl_node_t *high_node =
coarse_ravl_find_node(coarse_provider->all_blocks, highPtr);
if (high_node == NULL) {
LOG_ERR("the highPtr memory block not found");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

block_t *high_block = get_node_block(high_node);
if (!high_block->used) {
LOG_ERR("the highPtr block is not allocated");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

if (get_node_next(low_node) != high_node) {
LOG_ERR("given pointers cannot be merged");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

if (get_node_prev(high_node) != low_node) {
LOG_ERR("given pointers cannot be merged");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

if (low_block->size + high_block->size != totalSize) {
LOG_ERR("wrong totalSize");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

if ((uintptr_t)highPtr != ((uintptr_t)lowPtr + low_block->size)) {
LOG_ERR("given pointers cannot be merged");
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
goto err_mutex_unlock;
}

ravl_node_t *merged_node = NULL;

umf_result = user_block_merge(coarse_provider, low_node, high_node, true,
&merged_node);
if (umf_result != UMF_RESULT_SUCCESS) {
LOG_ERR("merging failed");
goto err_mutex_unlock;
}

assert(merged_node == low_node);
assert(low_block->size == totalSize);

umf_result = UMF_RESULT_SUCCESS;

err_mutex_unlock:
assert(debug_check(coarse_provider));

if (utils_mutex_unlock(&coarse_provider->lock) != 0) {
LOG_ERR("unlocking the lock failed");
if (umf_result == UMF_RESULT_SUCCESS) {
umf_result = UMF_RESULT_ERROR_UNKNOWN;
}
}

return umf_result;
}

umf_memory_provider_ops_t UMF_COARSE_MEMORY_PROVIDER_OPS = {
.version = UMF_VERSION_CURRENT,
.initialize = coarse_memory_provider_initialize,
Expand All @@ -1522,12 +1700,12 @@ umf_memory_provider_ops_t UMF_COARSE_MEMORY_PROVIDER_OPS = {
.get_min_page_size = coarse_memory_provider_get_min_page_size,
.get_name = coarse_memory_provider_get_name,
.ext.free = coarse_memory_provider_free,
.ext.allocation_merge = coarse_memory_provider_allocation_merge,
.ext.allocation_split = coarse_memory_provider_allocation_split,
// TODO
/*
.ext.purge_lazy = coarse_memory_provider_purge_lazy,
.ext.purge_force = coarse_memory_provider_purge_force,
.ext.allocation_merge = coarse_memory_provider_allocation_merge,
.ext.allocation_split = coarse_memory_provider_allocation_split,
.ipc.get_ipc_handle_size = coarse_memory_provider_get_ipc_handle_size,
.ipc.get_ipc_handle = coarse_memory_provider_get_ipc_handle,
.ipc.put_ipc_handle = coarse_memory_provider_put_ipc_handle,
Expand All @@ -1554,7 +1732,7 @@ umfCoarseMemoryProviderGetStats(umf_memory_provider_handle_t provider) {
(struct coarse_memory_provider_t *)priv;

if (utils_mutex_lock(&coarse_provider->lock) != 0) {
LOG_ERR("lockng the lock failed");
LOG_ERR("locking the lock failed");
return stats;
}

Expand Down
Loading

0 comments on commit 0ba0b97

Please sign in to comment.