Skip to content

[CTL] Add support for defaults #1320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

KFilipek
Copy link
Contributor

@KFilipek KFilipek commented May 19, 2025

Description

Checklist

  • Code compiles without errors locally
  • All tests pass locally
  • CI workflows execute properly

@KFilipek KFilipek self-assigned this May 19, 2025
@KFilipek KFilipek requested a review from a team as a code owner May 19, 2025 09:01
@KFilipek KFilipek added the enhancement New feature or request label May 19, 2025
@bratpiorka bratpiorka requested review from lplewa and bratpiorka May 19, 2025 09:28
const char *disjoint_pool_get_name(void *pool) {
disjoint_pool_t *hPool = (disjoint_pool_t *)pool;
if (pool == NULL) {
return "disjoint";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't we use the DEFAULT_NAME here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

};

*hParams = params;
// Find default name and update params name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean by "Find"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -168,6 +245,11 @@ umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool,
return UMF_RESULT_SUCCESS;
}

const char *umfPoolGetName(umf_memory_pool_handle_t pool) {
UMF_CHECK(pool != NULL, NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm not sure if I get this right - if pool == NULL we return NULL, and not the default pool name...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umfPoolGetName is an API function that needs a context.
I extended function to works in case when get_name callback is not set.

/// @brief Retrieves the name of the disjoint memory pool [optional]
/// @param pool pointer to the memory pool or NULL value
/// @return A constant character string representing the pool's name.
/// Returns "disjoint" if `pool` is NULL, otherwise returns the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we mention disjoint here? did you mean return default pool name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

void *arg, size_t size, umf_ctl_query_type_t queryType);

///
/// @brief Retrieves the name of the disjoint memory pool [optional]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it only for disjoint pool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

umfDisjointPoolParamsDestroy(params);
} catch (Pool::CtlException &e) {
umfDisjointPoolParamsDestroy(params);
GTEST_SKIP() << e.what();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why skip, can't we fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach is commonly used in our tests:

ctest --verbose | grep SKIP | wc -l
295

umf_memory_provider_handle_t provider_handle = nullptr;
umf_memory_pool_handle_t pool = NULL;

struct memory_provider : public umf_test::provider_base_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this struct in this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reworked separately. It follows the approach used in the disjoint pool tests.

res =
umfPoolCreate(umfDisjointPoolOps(), provider_handle, params, 0, &pool);
EXPECT_EQ(res, UMF_RESULT_SUCCESS);
const char *name = umfPoolGetName(pool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also test umfPoolGetName(null here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, umfPoolGetName() must take a valid pointer to the pool.

auto res = umfPoolCreate(m_poolOps, m_provider, m_params, 0, &m_pool);
if (res != UMF_RESULT_SUCCESS) {
m_pool = nullptr;
LOG_ERR("Failed to create memory pool");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if LOG in test is expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
Removed.

using umf_test::test;
using namespace umf_test;

#define RETURN_SUCCESS(ret) ASSERT_EQ(ret, UMF_RESULT_SUCCESS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you really want this macro to be here, perhaps rename to ASSERT_SUCCESS...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

src/libumf.c Outdated
Comment on lines 101 to 134

umf_result_t umfCtlGet(const char *name, void *ctx, void *arg, size_t size) {
if (name == NULL || arg == NULL) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ,
arg, size);
}

umf_result_t umfCtlSet(const char *name, void *ctx, void *arg, size_t size) {
// Context can be NULL when setting defaults
if (name == NULL || arg == NULL || size == 0) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE,
arg, size)
? UMF_RESULT_ERROR_UNKNOWN
: UMF_RESULT_SUCCESS;
}

umf_result_t umfCtlExec(const char *name, void *ctx, void *arg, size_t size) {
if (name == NULL || arg == NULL || ctx == NULL) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name,
CTL_QUERY_RUNNABLE, arg, size)
? UMF_RESULT_ERROR_UNKNOWN
: UMF_RESULT_SUCCESS;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is chaos in this inval check - please add comment per each function why we not check for null.

For sure exec should accept null arg.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 62 to 60
if (ctx && strstr(extra_name, "default")) {
utils_mutex_unlock(&ctl_mtx);
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this strstr? If yes what we are looking for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -22,13 +22,13 @@
#include "utils_assert.h"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is support for defaults for memory providers? I see only implementation for pools, and we need both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be splitted between 2 PR's

Comment on lines 147 to 155
/// @brief Retrieves the name of the disjoint memory pool [optional]
/// @param pool pointer to the memory pool or NULL value
/// @return A constant character string representing the pool's name.
/// Returns "disjoint" if `pool` is NULL, otherwise returns the
/// configured name of the specific pool instance.
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document requirements of interface - not how this function behaviors for disjoint pool

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

src/ctl/ctl.h Outdated
Comment on lines 191 to 202
/*
* Declaration of a new RW leaf. This type of RW leaf doesn't require parsing
* of the argument. The argument is passed directly to the read/write callback.
*/
#define CTL_LEAF_RW_no_arg(name, ...) \
{ \
CTL_STR(name), CTL_NODE_LEAF, \
{CTL_READ_HANDLER(name, __VA_ARGS__), \
CTL_WRITE_HANDLER(name, __VA_ARGS__), NULL, NULL}, \
NULL, NULL \
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, done.

@@ -21,35 +21,35 @@ TEST_F(test, ctl_debug_read_from_string) {

int value = 0;
ctl_query(ctl_handler, NULL, CTL_QUERY_PROGRAMMATIC,
"debug.heap.alloc_pattern", CTL_QUERY_READ, &value);
"debug.heap.alloc_pattern", CTL_QUERY_READ, &value, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my comment from the prev. PR is not resolved:

whenever size is used, please add a test with various values (user may give some input we may not expect, e.g. on wrong assumptions on how this func works) or mark a TODO for adding tests in the future

e.g. here you can simply add a repeated queries with non-zero values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

const char *extra_name,
umf_ctl_query_type_t query_type) {
(void)extra_name, (void)query_type;
assert(n != NULL);
assert(n->cb[CTL_QUERY_RUNNABLE] != NULL);
assert(MAX_CTL_QUERY_TYPE != query_type);
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes, NULL,
MAX_CTL_QUERY_TYPE);
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, size, indexes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra name is used so remove (void)extra_name few lines above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

umf_ctl_index_utlist_t *indexes,
const char *extra_name,
umf_ctl_query_type_t queryType) {
(void)indexes, (void)source, (void)ctx;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctx is used in if()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

umf_ctl_index_utlist_t *indexes,
const char *extra_name,
umf_ctl_query_type_t queryType) {
(void)source, (void)indexes, (void)queryType, (void)size, (void)extra_name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size is used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

umf_result_t disjoint_pool_ctl(void *hPool, int operationType, const char *name,
void *arg, size_t size,
umf_ctl_query_type_t queryType) {
(void)operationType, (void)queryType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryType is used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -12,6 +13,7 @@
#include "provider.hpp"
#include "provider_null.h"
#include "provider_trace.h"
#include "umf/memory_pool.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use <> and move up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@KFilipek KFilipek force-pushed the ctl-default branch 6 times, most recently from 3dbf762 to c43ddc7 Compare May 22, 2025 14:37
@KFilipek KFilipek force-pushed the ctl-default branch 2 times, most recently from e7f77ee to c28fe62 Compare May 22, 2025 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants