Skip to content

Commit 4369cf8

Browse files
committed
[CTL] Add support for defaults
1 parent 4a923b9 commit 4369cf8

19 files changed

+547
-135
lines changed

benchmark/benchmark_umf.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct provider_interface {
4545
return;
4646
}
4747
umfCtlExec("umf.provider.by_handle.stats.peak_memory.reset", provider,
48-
NULL);
48+
NULL, 0);
4949
}
5050

5151
void postBench([[maybe_unused]] ::benchmark::State &state) {
@@ -54,7 +54,7 @@ struct provider_interface {
5454
}
5555
size_t arg;
5656
umf_result_t ret = umfCtlGet(
57-
"umf.provider.by_handle.stats.allocated_memory", provider, &arg);
57+
"umf.provider.by_handle.stats.allocated_memory", provider, &arg, 0);
5858
if (ret == UMF_RESULT_SUCCESS) {
5959
state.counters["provider_memory_allocated"] =
6060
static_cast<double>(arg);

include/umf/base.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,30 @@ typedef enum umf_ctl_query_type {
6666
/// @param name name of an attribute to be retrieved
6767
/// @param ctx pointer to the pool or the provider
6868
/// @param arg [out] pointer to the variable where the value will be stored
69+
/// @param size size of the value, depends on the context
6970
/// @return UMF_RESULT_SUCCESS on success or UMF_RESULT_ERROR_UNKNOWN on failure.
7071
///
71-
umf_result_t umfCtlGet(const char *name, void *ctx, void *arg);
72+
umf_result_t umfCtlGet(const char *name, void *ctx, void *arg, size_t size);
7273

7374
///
7475
/// @brief Set value of a specified attribute at the given name.
7576
/// @param name name of an attribute to be set
76-
/// @param ctx pointer to the pool or the provider
77+
/// @param ctx pointer to the pool or the provider, NULL for the 'default' path
7778
/// @param arg [in] pointer to the value that will be set
79+
/// @param size [in] size of the value, depends on the context
7880
/// @return UMF_RESULT_SUCCESS on success or UMF_RESULT_ERROR_UNKNOWN on failure.
7981
///
80-
umf_result_t umfCtlSet(const char *name, void *ctx, void *arg);
82+
umf_result_t umfCtlSet(const char *name, void *ctx, void *arg, size_t size);
8183

8284
///
8385
/// @brief Execute callback related with the specified attribute.
8486
/// @param name name of an attribute to be executed
8587
/// @param ctx pointer to the pool or the provider
8688
/// @param arg [in/out] pointer to the value, can be used as an input or output
89+
/// @param size [in] size of the value, depends on the context
8790
/// @return UMF_RESULT_SUCCESS on success or UMF_RESULT_ERROR_UNKNOWN on failure.
8891
///
89-
umf_result_t umfCtlExec(const char *name, void *ctx, void *arg);
92+
umf_result_t umfCtlExec(const char *name, void *ctx, void *arg, size_t size);
9093

9194
#ifdef __cplusplus
9295
}

include/umf/memory_pool_ops.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,17 @@ typedef struct umf_memory_pool_ops_t {
131131
/// The function is used to perform various control operations
132132
/// on the memory pool.
133133
///
134-
/// @param hPool handle to the memory pool.
134+
/// @param pool handle to the memory pool.
135135
/// @param operationType type of the operation to be performed.
136136
/// @param name name associated with the operation.
137137
/// @param arg argument for the operation.
138+
/// @param size size of the argument [optional - check path requirements]
138139
/// @param queryType type of the query to be performed.
139140
///
140141
/// @return umf_result_t result of the control operation.
141142
///
142-
umf_result_t (*ctl)(void *hPool, int operationType, const char *name,
143-
void *arg, umf_ctl_query_type_t queryType);
143+
umf_result_t (*ctl)(void *pool, int operationType, const char *name,
144+
void *arg, size_t size, umf_ctl_query_type_t queryType);
144145

145146
///
146147
/// @brief Get the name of the memory pool.

include/umf/memory_provider_ops.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,13 @@ typedef struct umf_memory_provider_ops_t {
259259
/// @param operationType type of the operation to be performed.
260260
/// @param name name associated with the operation.
261261
/// @param arg argument for the operation.
262+
/// @param size TODO(kfilipek)
262263
/// @param queryType type of the query to be performed.
263264
///
264265
/// @return umf_result_t result of the control operation.
265266
///
266267
umf_result_t (*ctl)(void *hProvider, int operationType, const char *name,
267-
void *arg, umf_ctl_query_type_t queryType);
268+
void *arg, size_t size, umf_ctl_query_type_t queryType);
268269

269270
} umf_memory_provider_ops_t;
270271

src/ctl/ctl.c

+17-63
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
#include <stdio.h>
3737
#endif
3838

39-
#define CTL_MAX_ENTRIES 100
40-
4139
#define MAX_CONFIG_FILE_LEN (1 << 20) /* 1 megabyte */
4240

4341
#define CTL_STRING_QUERY_SEPARATOR ";"
@@ -49,21 +47,6 @@
4947
static int ctl_global_first_free = 0;
5048
static umf_ctl_node_t CTL_NODE(global)[CTL_MAX_ENTRIES];
5149

52-
/*
53-
* This is the top level node of the ctl tree structure. Each node can contain
54-
* children and leaf nodes.
55-
*
56-
* Internal nodes simply create a new path in the tree whereas child nodes are
57-
* the ones providing the read/write functionality by the means of callbacks.
58-
*
59-
* Each tree node must be NULL-terminated, CTL_NODE_END macro is provided for
60-
* convenience.
61-
*/
62-
struct ctl {
63-
umf_ctl_node_t root[CTL_MAX_ENTRIES];
64-
int first_free;
65-
};
66-
6750
void *Zalloc(size_t sz) {
6851
void *ptr = umf_ba_global_alloc(sz);
6952
if (ptr) {
@@ -81,36 +64,6 @@ char *Strdup(const char *s) {
8164
return p;
8265
}
8366

84-
umf_result_t umfCtlGet(const char *name, void *ctx, void *arg) {
85-
if (name == NULL || arg == NULL || ctx == NULL) {
86-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
87-
}
88-
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ,
89-
arg)
90-
? UMF_RESULT_ERROR_UNKNOWN
91-
: UMF_RESULT_SUCCESS;
92-
}
93-
94-
umf_result_t umfCtlSet(const char *name, void *ctx, void *arg) {
95-
if (name == NULL || arg == NULL || ctx == NULL) {
96-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
97-
}
98-
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE,
99-
arg)
100-
? UMF_RESULT_ERROR_UNKNOWN
101-
: UMF_RESULT_SUCCESS;
102-
}
103-
104-
umf_result_t umfCtlExec(const char *name, void *ctx, void *arg) {
105-
if (name == NULL || ctx == NULL) {
106-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
107-
}
108-
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name,
109-
CTL_QUERY_RUNNABLE, arg)
110-
? UMF_RESULT_ERROR_UNKNOWN
111-
: UMF_RESULT_SUCCESS;
112-
}
113-
11467
/*
11568
* ctl_find_node -- (internal) searches for a matching entry point in the
11669
* provided nodes
@@ -296,10 +249,10 @@ static void ctl_query_cleanup_real_args(const umf_ctl_node_t *n, void *real_arg,
296249
*/
297250
static int ctl_exec_query_read(void *ctx, const umf_ctl_node_t *n,
298251
umf_ctl_query_source_t source, void *arg,
299-
umf_ctl_index_utlist_t *indexes,
252+
size_t size, umf_ctl_index_utlist_t *indexes,
300253
const char *extra_name,
301254
umf_ctl_query_type_t query_type) {
302-
(void)extra_name, (void)query_type;
255+
(void)query_type;
303256
assert(n != NULL);
304257
assert(n->cb[CTL_QUERY_READ] != NULL);
305258
assert(MAX_CTL_QUERY_TYPE != query_type);
@@ -309,7 +262,7 @@ static int ctl_exec_query_read(void *ctx, const umf_ctl_node_t *n,
309262
return -1;
310263
}
311264

312-
return n->cb[CTL_QUERY_READ](ctx, source, arg, indexes, NULL,
265+
return n->cb[CTL_QUERY_READ](ctx, source, arg, size, indexes, extra_name,
313266
MAX_CTL_QUERY_TYPE);
314267
}
315268

@@ -318,10 +271,10 @@ static int ctl_exec_query_read(void *ctx, const umf_ctl_node_t *n,
318271
*/
319272
static int ctl_exec_query_write(void *ctx, const umf_ctl_node_t *n,
320273
umf_ctl_query_source_t source, void *arg,
321-
umf_ctl_index_utlist_t *indexes,
274+
size_t size, umf_ctl_index_utlist_t *indexes,
322275
const char *extra_name,
323276
umf_ctl_query_type_t query_type) {
324-
(void)extra_name, (void)query_type;
277+
(void)query_type;
325278
assert(n != NULL);
326279
assert(n->cb[CTL_QUERY_WRITE] != NULL);
327280
assert(MAX_CTL_QUERY_TYPE != query_type);
@@ -336,8 +289,8 @@ static int ctl_exec_query_write(void *ctx, const umf_ctl_node_t *n,
336289
return -1;
337290
}
338291

339-
int ret = n->cb[CTL_QUERY_WRITE](ctx, source, real_arg, indexes, NULL,
340-
MAX_CTL_QUERY_TYPE);
292+
int ret = n->cb[CTL_QUERY_WRITE](ctx, source, real_arg, size, indexes,
293+
extra_name, MAX_CTL_QUERY_TYPE);
341294
ctl_query_cleanup_real_args(n, real_arg, source);
342295

343296
return ret;
@@ -348,31 +301,32 @@ static int ctl_exec_query_write(void *ctx, const umf_ctl_node_t *n,
348301
*/
349302
static int ctl_exec_query_runnable(void *ctx, const umf_ctl_node_t *n,
350303
umf_ctl_query_source_t source, void *arg,
351-
umf_ctl_index_utlist_t *indexes,
304+
size_t size, umf_ctl_index_utlist_t *indexes,
352305
const char *extra_name,
353306
umf_ctl_query_type_t query_type) {
354307
(void)extra_name, (void)query_type;
355308
assert(n != NULL);
356309
assert(n->cb[CTL_QUERY_RUNNABLE] != NULL);
357310
assert(MAX_CTL_QUERY_TYPE != query_type);
358-
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, indexes, NULL,
359-
MAX_CTL_QUERY_TYPE);
311+
return n->cb[CTL_QUERY_RUNNABLE](ctx, source, arg, size, indexes,
312+
extra_name, MAX_CTL_QUERY_TYPE);
360313
}
361314

362315
static int ctl_exec_query_subtree(void *ctx, const umf_ctl_node_t *n,
363316
umf_ctl_query_source_t source, void *arg,
364-
umf_ctl_index_utlist_t *indexes,
317+
size_t size, umf_ctl_index_utlist_t *indexes,
365318
const char *extra_name,
366319
umf_ctl_query_type_t query_type) {
367320
assert(n != NULL);
368321
assert(n->cb[CTL_QUERY_SUBTREE] != NULL);
369322
assert(MAX_CTL_QUERY_TYPE != query_type);
370-
return n->cb[CTL_QUERY_SUBTREE](ctx, source, arg, indexes, extra_name,
323+
return n->cb[CTL_QUERY_SUBTREE](ctx, source, arg, size, indexes, extra_name,
371324
query_type);
372325
}
373326

374327
typedef int (*umf_ctl_exec_query_t)(void *ctx, const umf_ctl_node_t *n,
375328
umf_ctl_query_source_t source, void *arg,
329+
size_t size,
376330
umf_ctl_index_utlist_t *indexes,
377331
const char *extra_name,
378332
umf_ctl_query_type_t query_type);
@@ -389,7 +343,8 @@ static umf_ctl_exec_query_t ctl_exec_query[MAX_CTL_QUERY_TYPE] = {
389343
* from the ctl tree
390344
*/
391345
int ctl_query(struct ctl *ctl, void *ctx, umf_ctl_query_source_t source,
392-
const char *name, umf_ctl_query_type_t type, void *arg) {
346+
const char *name, umf_ctl_query_type_t type, void *arg,
347+
size_t size) {
393348
if (name == NULL) {
394349
errno = EINVAL;
395350
return -1;
@@ -426,10 +381,9 @@ int ctl_query(struct ctl *ctl, void *ctx, umf_ctl_query_source_t source,
426381
goto out;
427382
}
428383

429-
const char *extra_name = &name[0] + name_offset;
430384
ret =
431385
ctl_exec_query[n->type == CTL_NODE_SUBTREE ? CTL_QUERY_SUBTREE : type](
432-
ctx, n, source, arg, indexes, extra_name, type);
386+
ctx, n, source, arg, size, indexes, name + name_offset, type);
433387
out:
434388
ctl_delete_indexes(indexes);
435389

@@ -496,7 +450,7 @@ static int ctl_load_config(struct ctl *ctl, void *ctx, char *buf) {
496450
}
497451

498452
r = ctl_query(ctl, ctx, CTL_QUERY_CONFIG_INPUT, name, CTL_QUERY_WRITE,
499-
value);
453+
value, 0);
500454

501455
if (r < 0 && ctx != NULL) {
502456
return -1;

src/ctl/ctl.h

+20-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
extern "C" {
2828
#endif
2929

30-
struct ctl;
30+
#define CTL_MAX_ENTRIES 100
3131

3232
typedef struct ctl_index_utlist {
3333
const char *name;
@@ -46,7 +46,7 @@ typedef enum ctl_query_source {
4646
} umf_ctl_query_source_t;
4747

4848
typedef int (*node_callback)(void *ctx, umf_ctl_query_source_t type, void *arg,
49-
umf_ctl_index_utlist_t *indexes,
49+
size_t size, umf_ctl_index_utlist_t *indexes,
5050
const char *extra_name,
5151
umf_ctl_query_type_t query_type);
5252

@@ -98,8 +98,23 @@ typedef struct ctl_node {
9898
const struct ctl_node *children;
9999
} umf_ctl_node_t;
100100

101+
/*
102+
* This is the top level node of the ctl tree structure. Each node can contain
103+
* children and leaf nodes.
104+
*
105+
* Internal nodes simply create a new path in the tree whereas child nodes are
106+
* the ones providing the read/write functionality by the means of callbacks.
107+
*
108+
* Each tree node must be NULL-terminated, CTL_NODE_END macro is provided for
109+
* convenience.
110+
*/
111+
struct ctl {
112+
umf_ctl_node_t root[CTL_MAX_ENTRIES];
113+
int first_free;
114+
};
115+
101116
struct ctl *ctl_new(void);
102-
void ctl_delete(struct ctl *stats);
117+
void ctl_delete(struct ctl *c);
103118

104119
void initialize_global_ctl(void);
105120

@@ -138,7 +153,8 @@ int ctl_arg_string(const void *arg, void *dest, size_t dest_size);
138153
#define CTL_NODE(name, ...) ctl_node_##__VA_ARGS__##_##name
139154

140155
int ctl_query(struct ctl *ctl, void *ctx, umf_ctl_query_source_t source,
141-
const char *name, umf_ctl_query_type_t type, void *arg);
156+
const char *name, umf_ctl_query_type_t type, void *arg,
157+
size_t size);
142158

143159
/* Declaration of a new child node */
144160
#define CTL_CHILD(name, ...) \

src/libumf.c

+40
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <stddef.h>
11+
#include <string.h>
1112

1213
#include "base_alloc_global.h"
1314
#include "ipc_cache.h"
@@ -97,3 +98,42 @@ void umfTearDown(void) {
9798
}
9899

99100
int umfGetCurrentVersion(void) { return UMF_VERSION_CURRENT; }
101+
102+
umf_result_t umfCtlGet(const char *name, void *ctx, void *arg, size_t size) {
103+
if (name == NULL || arg == NULL) {
104+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
105+
}
106+
// using ctx is disallowed for default settings
107+
if (ctx && strstr(name, ".default.")) {
108+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
109+
}
110+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ,
111+
arg, size)
112+
? UMF_RESULT_ERROR_UNKNOWN
113+
: UMF_RESULT_SUCCESS;
114+
}
115+
116+
umf_result_t umfCtlSet(const char *name, void *ctx, void *arg, size_t size) {
117+
// Context can be NULL when setting defaults
118+
if (name == NULL || arg == NULL || size == 0) {
119+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
120+
}
121+
// using ctx is disallowed for default settings
122+
if (ctx && strstr(name, ".default.")) {
123+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
124+
}
125+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE,
126+
arg, size)
127+
? UMF_RESULT_ERROR_UNKNOWN
128+
: UMF_RESULT_SUCCESS;
129+
}
130+
131+
umf_result_t umfCtlExec(const char *name, void *ctx, void *arg, size_t size) {
132+
if (name == NULL || arg == NULL || ctx == NULL) {
133+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
134+
}
135+
return ctl_query(NULL, ctx, CTL_QUERY_PROGRAMMATIC, name,
136+
CTL_QUERY_RUNNABLE, arg, size)
137+
? UMF_RESULT_ERROR_UNKNOWN
138+
: UMF_RESULT_SUCCESS;
139+
}

0 commit comments

Comments
 (0)