Skip to content

Commit 2066e21

Browse files
committed
[CTL] Add CTL by handle
1 parent e31c856 commit 2066e21

18 files changed

+424
-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;
60+
61+
int umfCtlGet(const char *name, void *ctx, void *arg);
62+
int umfCtlSet(const char *name, void *ctx, void *arg);
63+
int umfCtlExec(const char *name, void *ctx, void *arg);
64+
5165
#ifdef __cplusplus
5266
}
5367
#endif

include/umf/memory_pool_ops.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@
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 extra_name additional name associated with the operation.
32+
/// @param query_type type of the query to be performed.
33+
///
34+
/// @return umf_result_t result of the control operation.
35+
///
36+
umf_result_t (*ctl)(void *hPool, int operationType, const char *name,
37+
void *arg, umf_ctl_query_type query_type);
38+
} umf_memory_pool_ext_ops_t;
39+
2040
///
2141
/// @brief This structure comprises function pointers used by corresponding umfPool*
2242
/// calls. Each memory pool implementation should initialize all function
@@ -120,6 +140,11 @@ typedef struct umf_memory_pool_ops_t {
120140
/// The value is undefined if the previous allocation was successful.
121141
///
122142
umf_result_t (*get_last_allocation_error)(void *pool);
143+
144+
///
145+
/// @brief Optional ops
146+
///
147+
umf_memory_provider_ext_ops_t ext;
123148
} umf_memory_pool_ops_t;
124149

125150
#ifdef __cplusplus

include/umf/memory_provider_ops.h

Lines changed: 18 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,23 @@ 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 extra_name additional name associated with the operation.
90+
/// @param query_type type of the query to be performed.
91+
///
92+
/// @return umf_result_t result of the control operation.
93+
///
94+
umf_result_t (*ctl)(void *hProvider, int operationType, const char *name,
95+
void *arg, umf_ctl_query_type query_type);
96+
8197
} umf_memory_provider_ext_ops_t;
8298

8399
///

src/ctl/ctl.c

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <string.h>
2626

2727
#include "base_alloc/base_alloc_global.h"
28+
#include "umf/base.h"
2829
#include "utils/utils_common.h"
2930
#include "utlist.h"
3031

@@ -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,33 @@ char *Strdup(const char *s) {
7880
return p;
7981
}
8082

83+
int umfCtlGet(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 umfCtlSet(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 umfCtlExec(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) {
91110
const struct ctl_node *n = NULL;
92111
char *sptr = NULL;
93112
char *parse_str = Strdup(name);
@@ -102,6 +121,10 @@ static const struct ctl_node *ctl_find_node(const struct ctl_node *nodes,
102121
* in the main ctl tree.
103122
*/
104123
while (node_name != NULL) {
124+
*name_offset = (int)(node_name - parse_str);
125+
if (n != NULL && n->type == CTL_NODE_SUBTREE) {
126+
break;
127+
}
105128
char *endptr;
106129
/*
107130
* Ignore errno from strtol: FreeBSD returns EINVAL if no
@@ -128,6 +151,7 @@ static const struct ctl_node *ctl_find_node(const struct ctl_node *nodes,
128151
break;
129152
}
130153
}
154+
131155
if (n->name == NULL) {
132156
goto error;
133157
}
@@ -244,21 +268,29 @@ static void ctl_query_cleanup_real_args(const struct ctl_node *n,
244268
*/
245269
static int ctl_exec_query_read(void *ctx, const struct ctl_node *n,
246270
enum ctl_query_source source, void *arg,
247-
struct ctl_index_utlist *indexes) {
271+
struct ctl_index_utlist *indexes,
272+
char *extra_name,
273+
umf_ctl_query_type query_type) {
274+
(void)extra_name, (void)query_type;
248275
if (arg == NULL) {
249276
errno = EINVAL;
250277
return -1;
251278
}
252279

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

256285
/*
257286
* ctl_exec_query_write -- (internal) calls the write callback of a node
258287
*/
259288
static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
260289
enum ctl_query_source source, void *arg,
261-
struct ctl_index_utlist *indexes) {
290+
struct ctl_index_utlist *indexes,
291+
char *extra_name,
292+
umf_ctl_query_type query_type) {
293+
(void)extra_name, (void)query_type;
262294
if (arg == NULL) {
263295
errno = EINVAL;
264296
return -1;
@@ -269,7 +301,9 @@ static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
269301
return -1;
270302
}
271303

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

275309
return ret;
@@ -280,24 +314,40 @@ static int ctl_exec_query_write(void *ctx, const struct ctl_node *n,
280314
*/
281315
static int ctl_exec_query_runnable(void *ctx, const struct ctl_node *n,
282316
enum ctl_query_source source, void *arg,
283-
struct ctl_index_utlist *indexes) {
284-
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes);
317+
struct ctl_index_utlist *indexes,
318+
char *extra_name,
319+
umf_ctl_query_type query_type) {
320+
(void)extra_name, (void)query_type;
321+
assert(MAX_CTL_QUERY_TYPE != query_type);
322+
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes, NULL,
323+
MAX_CTL_QUERY_TYPE);
324+
}
325+
326+
static int ctl_exec_query_subtree(void *ctx, const struct ctl_node *n,
327+
enum ctl_query_source source, void *arg,
328+
struct ctl_index_utlist *indexes,
329+
char *extra_name,
330+
umf_ctl_query_type query_type) {
331+
return n->cb[CTL_QUERY_SUBTREE](ctx, source, arg, indexes, extra_name,
332+
query_type);
285333
}
286334

287335
static int (*ctl_exec_query[MAX_CTL_QUERY_TYPE])(
288336
void *ctx, const struct ctl_node *n, enum ctl_query_source source,
289-
void *arg, struct ctl_index_utlist *indexes) = {
337+
void *arg, struct ctl_index_utlist *indexes, char *extra_name,
338+
umf_ctl_query_type query_type) = {
290339
ctl_exec_query_read,
291340
ctl_exec_query_write,
292341
ctl_exec_query_runnable,
342+
ctl_exec_query_subtree,
293343
};
294344

295345
/*
296346
* ctl_query -- (internal) parses the name and calls the appropriate methods
297347
* from the ctl tree
298348
*/
299349
int ctl_query(struct ctl *ctl, void *ctx, enum ctl_query_source source,
300-
const char *name, enum ctl_query_type type, void *arg) {
350+
const char *name, umf_ctl_query_type type, void *arg) {
301351
if (name == NULL) {
302352
errno = EINVAL;
303353
return -1;
@@ -315,22 +365,28 @@ int ctl_query(struct ctl *ctl, void *ctx, enum ctl_query_source source,
315365
}
316366

317367
int ret = -1;
368+
int name_offset = 0;
318369

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

321373
if (n == NULL && ctl) {
322374
ctl_delete_indexes(indexes);
323375
indexes = NULL;
324-
n = ctl_find_node(ctl->root, name, indexes);
376+
n = ctl_find_node(ctl->root, name, indexes, &name_offset);
325377
}
326378

327-
if (n == NULL || n->type != CTL_NODE_LEAF || n->cb[type] == NULL) {
379+
if (n == NULL ||
380+
(n->type != CTL_NODE_LEAF && n->type != CTL_NODE_SUBTREE) ||
381+
n->cb[n->type == CTL_NODE_SUBTREE ? CTL_QUERY_SUBTREE : type] == NULL) {
328382
errno = EINVAL;
329383
goto out;
330384
}
331385

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

0 commit comments

Comments
 (0)