Skip to content

Commit 3a5b33c

Browse files
committed
Implement split()/merge() API of the Coarse provider
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent ade200a commit 3a5b33c

File tree

2 files changed

+392
-6
lines changed

2 files changed

+392
-6
lines changed

src/provider/provider_coarse.c

Lines changed: 184 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ static umf_result_t coarse_memory_provider_alloc(void *provider, size_t size,
12091209
(struct coarse_memory_provider_t *)provider;
12101210

12111211
if (utils_mutex_lock(&coarse_provider->lock) != 0) {
1212-
LOG_ERR("lockng the lock failed");
1212+
LOG_ERR("locking the lock failed");
12131213
return UMF_RESULT_ERROR_UNKNOWN;
12141214
}
12151215

@@ -1335,7 +1335,7 @@ static umf_result_t coarse_memory_provider_free(void *provider, void *ptr,
13351335
(struct coarse_memory_provider_t *)provider;
13361336

13371337
if (utils_mutex_lock(&coarse_provider->lock) != 0) {
1338-
LOG_ERR("lockng the lock failed");
1338+
LOG_ERR("locking the lock failed");
13391339
return UMF_RESULT_ERROR_UNKNOWN;
13401340
}
13411341

@@ -1357,7 +1357,12 @@ static umf_result_t coarse_memory_provider_free(void *provider, void *ptr,
13571357
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
13581358
}
13591359

1360-
assert(bytes == 0 || bytes == block->size);
1360+
if (bytes > 0 && bytes != block->size) {
1361+
// wrong size of allocation
1362+
utils_mutex_unlock(&coarse_provider->lock);
1363+
LOG_ERR("wrong size of allocation");
1364+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
1365+
}
13611366

13621367
LOG_DEBUG("coarse_FREE (return_block_to_pool) %zu used %zu alloc %zu",
13631368
block->size, coarse_provider->used_size - block->size,
@@ -1517,6 +1522,179 @@ coarse_memory_provider_get_stats(void *provider,
15171522
return UMF_RESULT_SUCCESS;
15181523
}
15191524

1525+
static umf_result_t coarse_memory_provider_allocation_split(void *provider,
1526+
void *ptr,
1527+
size_t totalSize,
1528+
size_t firstSize) {
1529+
if (provider == NULL || ptr == NULL || (firstSize >= totalSize) ||
1530+
firstSize == 0) {
1531+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
1532+
}
1533+
1534+
umf_result_t umf_result;
1535+
1536+
coarse_memory_provider_t *coarse_provider =
1537+
(struct coarse_memory_provider_t *)provider;
1538+
1539+
if (utils_mutex_lock(&coarse_provider->lock) != 0) {
1540+
LOG_ERR("locking the lock failed");
1541+
return UMF_RESULT_ERROR_UNKNOWN;
1542+
}
1543+
1544+
assert(debug_check(coarse_provider));
1545+
1546+
ravl_node_t *node = coarse_ravl_find_node(coarse_provider->all_blocks, ptr);
1547+
if (node == NULL) {
1548+
LOG_ERR("memory block not found");
1549+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1550+
goto err_mutex_unlock;
1551+
}
1552+
1553+
block_t *block = get_node_block(node);
1554+
1555+
if (block->size != totalSize) {
1556+
LOG_ERR("wrong totalSize");
1557+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1558+
goto err_mutex_unlock;
1559+
}
1560+
1561+
if (!block->used) {
1562+
LOG_ERR("block is not allocated");
1563+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1564+
goto err_mutex_unlock;
1565+
}
1566+
1567+
block_t *new_block = coarse_ravl_add_new(coarse_provider->all_blocks,
1568+
block->data + firstSize,
1569+
block->size - firstSize, NULL);
1570+
if (new_block == NULL) {
1571+
umf_result = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
1572+
goto err_mutex_unlock;
1573+
}
1574+
1575+
block->size = firstSize;
1576+
new_block->used = true;
1577+
1578+
assert(new_block->size == (totalSize - firstSize));
1579+
1580+
umf_result = UMF_RESULT_SUCCESS;
1581+
1582+
err_mutex_unlock:
1583+
assert(debug_check(coarse_provider));
1584+
1585+
if (utils_mutex_unlock(&coarse_provider->lock) != 0) {
1586+
LOG_ERR("unlocking the lock failed");
1587+
if (umf_result == UMF_RESULT_SUCCESS) {
1588+
umf_result = UMF_RESULT_ERROR_UNKNOWN;
1589+
}
1590+
}
1591+
1592+
return umf_result;
1593+
}
1594+
1595+
static umf_result_t coarse_memory_provider_allocation_merge(void *provider,
1596+
void *lowPtr,
1597+
void *highPtr,
1598+
size_t totalSize) {
1599+
if (provider == NULL || lowPtr == NULL || highPtr == NULL ||
1600+
((uintptr_t)highPtr <= (uintptr_t)lowPtr) ||
1601+
((uintptr_t)highPtr - (uintptr_t)lowPtr >= totalSize)) {
1602+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
1603+
}
1604+
1605+
umf_result_t umf_result;
1606+
1607+
coarse_memory_provider_t *coarse_provider =
1608+
(struct coarse_memory_provider_t *)provider;
1609+
1610+
if (utils_mutex_lock(&coarse_provider->lock) != 0) {
1611+
LOG_ERR("locking the lock failed");
1612+
return UMF_RESULT_ERROR_UNKNOWN;
1613+
}
1614+
1615+
assert(debug_check(coarse_provider));
1616+
1617+
ravl_node_t *low_node =
1618+
coarse_ravl_find_node(coarse_provider->all_blocks, lowPtr);
1619+
if (low_node == NULL) {
1620+
LOG_ERR("the lowPtr memory block not found");
1621+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1622+
goto err_mutex_unlock;
1623+
}
1624+
1625+
block_t *low_block = get_node_block(low_node);
1626+
if (!low_block->used) {
1627+
LOG_ERR("the lowPtr block is not allocated");
1628+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1629+
goto err_mutex_unlock;
1630+
}
1631+
1632+
ravl_node_t *high_node =
1633+
coarse_ravl_find_node(coarse_provider->all_blocks, highPtr);
1634+
if (high_node == NULL) {
1635+
LOG_ERR("the highPtr memory block not found");
1636+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1637+
goto err_mutex_unlock;
1638+
}
1639+
1640+
block_t *high_block = get_node_block(high_node);
1641+
if (!high_block->used) {
1642+
LOG_ERR("the highPtr block is not allocated");
1643+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1644+
goto err_mutex_unlock;
1645+
}
1646+
1647+
if (get_node_next(low_node) != high_node) {
1648+
LOG_ERR("given pointers cannot be merged");
1649+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1650+
goto err_mutex_unlock;
1651+
}
1652+
1653+
if (get_node_prev(high_node) != low_node) {
1654+
LOG_ERR("given pointers cannot be merged");
1655+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1656+
goto err_mutex_unlock;
1657+
}
1658+
1659+
if (low_block->size + high_block->size != totalSize) {
1660+
LOG_ERR("wrong totalSize");
1661+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1662+
goto err_mutex_unlock;
1663+
}
1664+
1665+
if ((uintptr_t)highPtr != ((uintptr_t)lowPtr + low_block->size)) {
1666+
LOG_ERR("given pointers cannot be merged");
1667+
umf_result = UMF_RESULT_ERROR_INVALID_ARGUMENT;
1668+
goto err_mutex_unlock;
1669+
}
1670+
1671+
ravl_node_t *merged_node = NULL;
1672+
1673+
umf_result = user_block_merge(coarse_provider, low_node, high_node, true,
1674+
&merged_node);
1675+
if (umf_result != UMF_RESULT_SUCCESS) {
1676+
LOG_ERR("merging failed");
1677+
goto err_mutex_unlock;
1678+
}
1679+
1680+
assert(merged_node == low_node);
1681+
assert(low_block->size == totalSize);
1682+
1683+
umf_result = UMF_RESULT_SUCCESS;
1684+
1685+
err_mutex_unlock:
1686+
assert(debug_check(coarse_provider));
1687+
1688+
if (utils_mutex_unlock(&coarse_provider->lock) != 0) {
1689+
LOG_ERR("unlocking the lock failed");
1690+
if (umf_result == UMF_RESULT_SUCCESS) {
1691+
umf_result = UMF_RESULT_ERROR_UNKNOWN;
1692+
}
1693+
}
1694+
1695+
return umf_result;
1696+
}
1697+
15201698
umf_memory_provider_ops_t UMF_COARSE_MEMORY_PROVIDER_OPS = {
15211699
.version = UMF_VERSION_CURRENT,
15221700
.initialize = coarse_memory_provider_initialize,
@@ -1528,12 +1706,12 @@ umf_memory_provider_ops_t UMF_COARSE_MEMORY_PROVIDER_OPS = {
15281706
.get_min_page_size = coarse_memory_provider_get_min_page_size,
15291707
.get_name = coarse_memory_provider_get_name,
15301708
.ext.free = coarse_memory_provider_free,
1709+
.ext.allocation_merge = coarse_memory_provider_allocation_merge,
1710+
.ext.allocation_split = coarse_memory_provider_allocation_split,
15311711
// TODO
15321712
/*
15331713
.ext.purge_lazy = coarse_memory_provider_purge_lazy,
15341714
.ext.purge_force = coarse_memory_provider_purge_force,
1535-
.ext.allocation_merge = coarse_memory_provider_allocation_merge,
1536-
.ext.allocation_split = coarse_memory_provider_allocation_split,
15371715
.ipc.get_ipc_handle_size = coarse_memory_provider_get_ipc_handle_size,
15381716
.ipc.get_ipc_handle = coarse_memory_provider_get_ipc_handle,
15391717
.ipc.put_ipc_handle = coarse_memory_provider_put_ipc_handle,
@@ -1560,7 +1738,7 @@ umfCoarseMemoryProviderGetStats(umf_memory_provider_handle_t provider) {
15601738
(struct coarse_memory_provider_t *)priv;
15611739

15621740
if (utils_mutex_lock(&coarse_provider->lock) != 0) {
1563-
LOG_ERR("lockng the lock failed");
1741+
LOG_ERR("locking the lock failed");
15641742
return stats;
15651743
}
15661744

0 commit comments

Comments
 (0)