Skip to content

Commit 5b63a6c

Browse files
committed
[CTL] Add CTL functionality (by handle access)
This commit introduces the control and introspection mechanism that can be accessed using pointer to supported pool or provider.
1 parent e31c856 commit 5b63a6c

18 files changed

+425
-55
lines changed

include/umf/base.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023-2024 Intel Corporation
3+
* Copyright (C) 2023-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -48,6 +48,20 @@ typedef enum umf_result_t {
4848
UMF_RESULT_ERROR_UNKNOWN = 0x7ffffffe ///< Unknown or internal error
4949
} umf_result_t;
5050

51+
/// @brief Type of the CTL query
52+
typedef enum umf_ctl_query_type {
53+
CTL_QUERY_READ,
54+
CTL_QUERY_WRITE,
55+
CTL_QUERY_RUNNABLE,
56+
CTL_QUERY_SUBTREE,
57+
58+
MAX_CTL_QUERY_TYPE
59+
} umf_ctl_query_type_t;
60+
61+
int umf_ctl_get(const char *name, void *ctx, void *arg);
62+
int umf_ctl_set(const char *name, void *ctx, void *arg);
63+
int umf_ctl_exec(const char *name, void *ctx, void *arg);
64+
5165
#ifdef __cplusplus
5266
}
5367
#endif

include/umf/memory_pool_ops.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,25 @@
1717
extern "C" {
1818
#endif
1919

20+
/// @brief This structure comprises function pointers used by corresponding umfMemoryPool calls.
21+
typedef struct umf_memory_pool_ext_ops_t {
22+
///
23+
/// @brief Control operation for the memory pool.
24+
/// The function is used to perform various control operations
25+
/// on the memory pool.
26+
///
27+
/// @param hPool handle to the memory pool.
28+
/// @param operationType type of the operation to be performed.
29+
/// @param name name associated with the operation.
30+
/// @param arg argument for the operation.
31+
/// @param query_type type of the query to be performed.
32+
///
33+
/// @return umf_result_t result of the control operation.
34+
///
35+
umf_result_t (*ctl)(void *hPool, int operationType, const char *name,
36+
void *arg, umf_ctl_query_type_t query_type);
37+
} umf_memory_pool_ext_ops_t;
38+
2039
///
2140
/// @brief This structure comprises function pointers used by corresponding umfPool*
2241
/// calls. Each memory pool implementation should initialize all function
@@ -120,6 +139,11 @@ typedef struct umf_memory_pool_ops_t {
120139
/// The value is undefined if the previous allocation was successful.
121140
///
122141
umf_result_t (*get_last_allocation_error)(void *pool);
142+
143+
///
144+
/// @brief Optional ops
145+
///
146+
umf_memory_provider_ext_ops_t ext;
123147
} umf_memory_pool_ops_t;
124148

125149
#ifdef __cplusplus

include/umf/memory_provider_ops.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
/*
22
*
3-
* Copyright (C) 2023-2024 Intel Corporation
3+
* Copyright (C) 2023-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
77
*
88
*/
9-
109
#ifndef UMF_MEMORY_PROVIDER_OPS_H
1110
#define UMF_MEMORY_PROVIDER_OPS_H 1
1211

@@ -78,6 +77,22 @@ typedef struct umf_memory_provider_ext_ops_t {
7877
umf_result_t (*allocation_split)(void *hProvider, void *ptr,
7978
size_t totalSize, size_t firstSize);
8079

80+
///
81+
/// @brief Control operation for the memory provider.
82+
/// The function is used to perform various control operations
83+
/// on the memory provider.
84+
///
85+
/// @param hProvider handle to the memory provider.
86+
/// @param operationType type of the operation to be performed.
87+
/// @param name name associated with the operation.
88+
/// @param arg argument for the operation.
89+
/// @param query_type type of the query to be performed.
90+
///
91+
/// @return umf_result_t result of the control operation.
92+
///
93+
umf_result_t (*ctl)(void *hProvider, int operationType, const char *name,
94+
void *arg, umf_ctl_query_type_t query_type);
95+
8196
} umf_memory_provider_ext_ops_t;
8297

8398
///

src/ctl/ctl.c

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "base_alloc/base_alloc_global.h"
2828
#include "utils/utils_common.h"
2929
#include "utlist.h"
30+
#include <umf/base.h>
3031

3132
#ifdef _WIN32
3233
#define strtok_r strtok_s
@@ -43,6 +44,7 @@
4344
#define CTL_QUERY_NODE_SEPARATOR "."
4445
#define CTL_VALUE_ARG_SEPARATOR ","
4546

47+
/* GLOBAL TREE */
4648
static int ctl_global_first_free = 0;
4749
static struct ctl_node CTL_NODE(global)[CTL_MAX_ENTRIES];
4850

@@ -78,16 +80,34 @@ char *Strdup(const char *s) {
7880
return p;
7981
}
8082

83+
int umf_ctl_get(const char *name, void *ctx, void *arg) {
84+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ,
85+
arg);
86+
}
87+
88+
int umf_ctl_set(const char *name, void *ctx, void *arg) {
89+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE,
90+
arg);
91+
}
92+
93+
int umf_ctl_exec(const char *name, void *ctx, void *arg) {
94+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name,
95+
CTL_QUERY_RUNNABLE, arg);
96+
}
97+
8198
/*
8299
* ctl_find_node -- (internal) searches for a matching entry point in the
83100
* provided nodes
84101
*
102+
* Name offset is used to return the offset of the name in the query string.
85103
* The caller is responsible for freeing all of the allocated indexes,
86104
* regardless of the return value.
87105
*/
88106
static const struct ctl_node *ctl_find_node(const struct ctl_node *nodes,
89107
const char *name,
90-
struct ctl_index_utlist *indexes) {
108+
struct ctl_index_utlist *indexes,
109+
int *name_offset) {
110+
assert(name_offset != NULL);
91111
const struct ctl_node *n = NULL;
92112
char *sptr = NULL;
93113
char *parse_str = Strdup(name);
@@ -102,6 +122,10 @@ static const struct ctl_node *ctl_find_node(const struct ctl_node *nodes,
102122
* in the main ctl tree.
103123
*/
104124
while (node_name != NULL) {
125+
*name_offset = (int)(node_name - parse_str);
126+
if (n != NULL && n->type == CTL_NODE_SUBTREE) {
127+
break;
128+
}
105129
char *endptr;
106130
/*
107131
* Ignore errno from strtol: FreeBSD returns EINVAL if no
@@ -128,6 +152,7 @@ static const struct ctl_node *ctl_find_node(const struct ctl_node *nodes,
128152
break;
129153
}
130154
}
155+
131156
if (n->name == NULL) {
132157
goto error;
133158
}
@@ -244,21 +269,29 @@ static void ctl_query_cleanup_real_args(const struct ctl_node *n,
244269
*/
245270
static int ctl_exec_query_read(void *ctx, const struct ctl_node *n,
246271
enum ctl_query_source source, void *arg,
247-
struct ctl_index_utlist *indexes) {
272+
struct ctl_index_utlist *indexes,
273+
char *extra_name,
274+
umf_ctl_query_type_t query_type) {
275+
(void)extra_name, (void)query_type;
248276
if (arg == NULL) {
249277
errno = EINVAL;
250278
return -1;
251279
}
252280

253-
return n->cb[CTL_QUERY_READ](ctx, source, arg, indexes);
281+
assert(MAX_CTL_QUERY_TYPE != query_type);
282+
return n->cb[CTL_QUERY_READ](ctx, source, arg, indexes, NULL,
283+
MAX_CTL_QUERY_TYPE);
254284
}
255285

256286
/*
257287
* ctl_exec_query_write -- (internal) calls the write callback of a node
258288
*/
259289
static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
260290
enum ctl_query_source source, void *arg,
261-
struct ctl_index_utlist *indexes) {
291+
struct ctl_index_utlist *indexes,
292+
char *extra_name,
293+
umf_ctl_query_type_t query_type) {
294+
(void)extra_name, (void)query_type;
262295
if (arg == NULL) {
263296
errno = EINVAL;
264297
return -1;
@@ -269,7 +302,9 @@ static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
269302
return -1;
270303
}
271304

272-
int ret = n->cb[CTL_QUERY_WRITE](ctx, source, real_arg, indexes);
305+
assert(MAX_CTL_QUERY_TYPE != query_type);
306+
int ret = n->cb[CTL_QUERY_WRITE](ctx, source, real_arg, indexes, NULL,
307+
MAX_CTL_QUERY_TYPE);
273308
ctl_query_cleanup_real_args(n, real_arg, source);
274309

275310
return ret;
@@ -280,24 +315,40 @@ static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
280315
*/
281316
static int ctl_exec_query_runnable(void *ctx, const struct ctl_node *n,
282317
enum ctl_query_source source, void *arg,
283-
struct ctl_index_utlist *indexes) {
284-
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes);
318+
struct ctl_index_utlist *indexes,
319+
char *extra_name,
320+
umf_ctl_query_type_t query_type) {
321+
(void)extra_name, (void)query_type;
322+
assert(MAX_CTL_QUERY_TYPE != query_type);
323+
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes, NULL,
324+
MAX_CTL_QUERY_TYPE);
325+
}
326+
327+
static int ctl_exec_query_subtree(void *ctx, const struct ctl_node *n,
328+
enum ctl_query_source source, void *arg,
329+
struct ctl_index_utlist *indexes,
330+
char *extra_name,
331+
umf_ctl_query_type_t query_type) {
332+
return n->cb[CTL_QUERY_SUBTREE](ctx, source, arg, indexes, extra_name,
333+
query_type);
285334
}
286335

287336
static int (*ctl_exec_query[MAX_CTL_QUERY_TYPE])(
288337
void *ctx, const struct ctl_node *n, enum ctl_query_source source,
289-
void *arg, struct ctl_index_utlist *indexes) = {
338+
void *arg, struct ctl_index_utlist *indexes, char *extra_name,
339+
umf_ctl_query_type_t query_type) = {
290340
ctl_exec_query_read,
291341
ctl_exec_query_write,
292342
ctl_exec_query_runnable,
343+
ctl_exec_query_subtree,
293344
};
294345

295346
/*
296347
* ctl_query -- (internal) parses the name and calls the appropriate methods
297348
* from the ctl tree
298349
*/
299350
int ctl_query(struct ctl *ctl, void *ctx, enum ctl_query_source source,
300-
const char *name, enum ctl_query_type type, void *arg) {
351+
const char *name, umf_ctl_query_type_t type, void *arg) {
301352
if (name == NULL) {
302353
errno = EINVAL;
303354
return -1;
@@ -315,22 +366,28 @@ int ctl_query(struct ctl *ctl, void *ctx, enum ctl_query_source source,
315366
}
316367

317368
int ret = -1;
369+
int name_offset = 0;
318370

319-
const struct ctl_node *n = ctl_find_node(CTL_NODE(global), name, indexes);
371+
const struct ctl_node *n =
372+
ctl_find_node(CTL_NODE(global), name, indexes, &name_offset);
320373

321374
if (n == NULL && ctl) {
322375
ctl_delete_indexes(indexes);
323376
indexes = NULL;
324-
n = ctl_find_node(ctl->root, name, indexes);
377+
n = ctl_find_node(ctl->root, name, indexes, &name_offset);
325378
}
326379

327-
if (n == NULL || n->type != CTL_NODE_LEAF || n->cb[type] == NULL) {
380+
if (n == NULL ||
381+
(n->type != CTL_NODE_LEAF && n->type != CTL_NODE_SUBTREE) ||
382+
n->cb[n->type == CTL_NODE_SUBTREE ? CTL_QUERY_SUBTREE : type] == NULL) {
328383
errno = EINVAL;
329384
goto out;
330385
}
331386

332-
ret = ctl_exec_query[type](ctx, n, source, arg, indexes);
333-
387+
char *extra_name = (char *)&name[0] + name_offset;
388+
ret =
389+
ctl_exec_query[n->type == CTL_NODE_SUBTREE ? CTL_QUERY_SUBTREE : type](
390+
ctx, n, source, arg, indexes, extra_name, type);
334391
out:
335392
ctl_delete_indexes(indexes);
336393

0 commit comments

Comments
 (0)