Skip to content

Commit b9d222c

Browse files
Merge pull request oracle#52 from drakenclimber/shared-data
adaptived: Add support for sharing data between causes and effects
2 parents bf6bb6c + 8774693 commit b9d222c

File tree

9 files changed

+1048
-52
lines changed

9 files changed

+1048
-52
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,6 @@ jobs:
8585
env:
8686
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
8787

88-
distcheck_cgv1:
89-
name: Adaptived make distcheck v1
90-
runs-on: ubuntu-20.04
91-
92-
steps:
93-
- uses: actions/checkout@v3
94-
with:
95-
submodules: false
96-
- name: Initialize the directory
97-
uses: ./.github/actions/setup-adaptived
98-
- name: Run make distcheck
99-
run: cd adaptived && make distcheck
100-
- name: Display test logs
101-
if: ${{ failure() }}
102-
run: |
103-
cat adaptived/adaptived-*/_build/sub/tests/ftests/ftests-wrapper.sh.log
104-
cat adaptived/adaptived-*/_build/sub/tests/ftests/ftests-c-wrapper.sh.log
105-
10688
distcheck_cgv2:
10789
name: Adaptived make distcheck v2
10890
runs-on: ubuntu-latest
@@ -121,37 +103,6 @@ jobs:
121103
cat adaptived/adaptived-*/_build/sub/tests/ftests/ftests-wrapper.sh.log
122104
cat adaptived/adaptived-*/_build/sub/tests/ftests/ftests-c-wrapper.sh.log
123105
124-
functional_tests_cgv1:
125-
name: Adaptived Functional Tests v1
126-
runs-on: ubuntu-20.04
127-
128-
steps:
129-
- uses: actions/checkout@v3
130-
with:
131-
submodules: false
132-
- name: Fail on all warnings
133-
run: |
134-
CFLAGS=-Werror
135-
export CFLAGS
136-
- name: Initialize the directory
137-
uses: ./.github/actions/setup-adaptived
138-
- name: Run functional tests
139-
run: cd adaptived && make check
140-
- name: Display test logs
141-
if: ${{ always() }}
142-
run: |
143-
cat adaptived/tests/ftests/ftests-wrapper.sh.log
144-
cat adaptived/tests/ftests/ftests-c-wrapper.sh.log
145-
- name: Collate code coverage results
146-
uses: ./.github/actions/code-coverage
147-
- name: Upload code coverage results
148-
uses: coverallsapp/github-action@master
149-
with:
150-
github-token: ${{ secrets.GITHUB_TOKEN }}
151-
path-to-lcov: ./lcov.total
152-
flag-name: "Adaptived Functional Tests - cgv1"
153-
parallel: True
154-
155106
functional_tests_cgv2:
156107
name: Adaptived Functional Tests v2
157108
runs-on: ubuntu-latest
@@ -186,7 +137,7 @@ jobs:
186137
finalize:
187138
name: Finalize the test run
188139
if: ${{ always() }}
189-
needs: [functional_tests_cgv1, functional_tests_cgv2]
140+
needs: [functional_tests_cgv2]
190141
runs-on: ubuntu-latest
191142
steps:
192143
- name: Finalize code coverage results

adaptived/include/adaptived.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,29 @@ enum adaptived_attr {
6363
ADAPTIVED_ATTR_CNT
6464
};
6565

66+
enum adaptived_sdata_type {
67+
/*
68+
* Custom data. Can be used by registered functions without forcing a recompile
69+
* of adaptived
70+
*/
71+
ADAPTIVED_SDATA_CUSTOM = 0,
72+
ADAPTIVED_SDATA_STR,
73+
ADAPTIVED_SDATA_CGROUP,
74+
ADAPTIVED_SDATA_NAME_VALUE,
75+
76+
ADAPTIVED_SDATA_CNT
77+
};
78+
79+
enum adaptived_sdata_flags {
80+
ADAPTIVED_SDATAF_PERSIST = 0x1
81+
};
82+
83+
/**
84+
* Function to free a custom shared data structure. Not needed for any other
85+
* shared data type, as adaptived knows how to free built-in data types.
86+
*/
87+
typedef void (*adaptived_sdata_free)(void * const data);
88+
6689
enum adaptived_cgroup_value_type {
6790
ADAPTIVED_CGVAL_STR = 0,
6891
ADAPTIVED_CGVAL_LONG_LONG,
@@ -89,6 +112,11 @@ struct adaptived_cgroup_value {
89112
} value;
90113
};
91114

115+
struct adaptived_name_and_value {
116+
char *name;
117+
struct adaptived_cgroup_value *value;
118+
};
119+
92120
struct adaptived_rule_stats {
93121
int cause_cnt;
94122
int effect_cnt;
@@ -459,6 +487,66 @@ int adaptived_load_rule(struct adaptived_ctx * const ctx, struct adaptived_rule
459487
*/
460488
int adaptived_unload_rule(struct adaptived_ctx * const ctx, const char * const name);
461489

490+
/**
491+
* Method to write shared data to a cause. Data can be used by downstream effect(s)
492+
* @param cse adaptived cause structure
493+
* @param type shared data enumeration describing the type of data being store
494+
* @param data pointer to the data to be stored
495+
* @param free_fn Function to free the shared data. Only needed for custom data types
496+
* @param flags See enum adaptived_sdata_flags
497+
*
498+
* @note - shared data is deleted/freed at the end of each adaptive main loop unless
499+
* the persist flag is set
500+
* @note - freeing of data is done by free(), so the *data pointer must be created
501+
* via malloc. It would be possible to avoid this by creating a new type,
502+
* e.g. ADAPTIVED_SDATA_INT, and adding handling for it in free_shared_data().
503+
* @note - persist can be used to share data bidirectionally between a cause and some
504+
* effect(s). Use with caution, as this tightly couples these causes and
505+
* effect(s).
506+
*/
507+
int adaptived_write_shared_data(struct adaptived_cause * const cse,
508+
enum adaptived_sdata_type type, void *data,
509+
adaptived_sdata_free free_fn,
510+
uint32_t flags);
511+
512+
/**
513+
* Update shared data
514+
* @param cse adaptived cause structure
515+
* @param index shared data object index
516+
* @param type shared data enumeration describing the type of data being store
517+
* @param data pointer to the data to be stored
518+
* @param flags See enum adaptived_sdata_flags
519+
*
520+
* @note - If the data pointer is changed, it's up to the caller of this function
521+
* to ensure that the previous *data pointer is freed.
522+
*/
523+
int adaptived_update_shared_data(struct adaptived_cause * const cse, int index,
524+
enum adaptived_sdata_type type, void *data,
525+
uint32_t flags);
526+
527+
/**
528+
* Get the number of shared data objects in this cause
529+
* @param cse adaptived cause
530+
*
531+
* @return number of shared data objects
532+
*/
533+
int adaptived_get_shared_data_cnt(const struct adaptived_cause * const cse);
534+
535+
/**
536+
* Retrieve one shared data object from the cause
537+
* @param cse adaptived cause
538+
* @param index shared data object index
539+
* @param type Output parameter that tells what type of data is stored in this object
540+
* @param data Output parameter that contains the stored data
541+
* @param flags See enum adaptived_sdata_flags
542+
*
543+
* @note You do not need to free the data in the shared data object. adaptived will
544+
* automatically do that at the end of each main processing loop
545+
*/
546+
int adaptived_get_shared_data(const struct adaptived_cause * const cse, int index,
547+
enum adaptived_sdata_type * const type, void **data,
548+
uint32_t * const flags);
549+
462550
#ifdef __cplusplus
463551
} /* extern "C" */
464552
#endif

adaptived/src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ SOURCES = \
3838
parse.c \
3939
pressure.h \
4040
rule.c \
41+
shared_data.c \
42+
shared_data.h \
4143
utils/cgroup_utils.c \
4244
utils/sd_bus_utils.c \
4345
utils/file_utils.c \

adaptived/src/cause.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ struct adaptived_cause {
7575
struct json_object *json; /* only used when building a rule at runtime */
7676
struct adaptived_cause *next;
7777

78+
/*
79+
* Data that can be shared between causes and effects. It is freed/deleted
80+
* at the end of each adaptived_loop() loop
81+
*/
82+
struct shared_data *sdata;
83+
7884
/* private data store for each cause plugin */
7985
void *data;
8086
};

adaptived/src/main.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <adaptived.h>
4040

4141
#include "adaptived-internal.h"
42+
#include "shared_data.h"
4243
#include "defines.h"
4344

4445
void cleanup(struct adaptived_ctx *ctx);
@@ -426,6 +427,18 @@ API int adaptived_register_injection_function(struct adaptived_ctx * const ctx,
426427
return 0;
427428
}
428429

430+
static void free_rule_shared_data(struct adaptived_rule * const rule, bool force_delete)
431+
{
432+
struct adaptived_cause *cse;
433+
434+
cse = rule->causes;
435+
436+
while(cse) {
437+
free_shared_data(cse, force_delete);
438+
cse = cse->next;
439+
}
440+
}
441+
429442
API int adaptived_loop(struct adaptived_ctx * const ctx, bool parse)
430443
{
431444
struct adaptived_effect *eff;
@@ -534,7 +547,7 @@ API int adaptived_loop(struct adaptived_ctx * const ctx, bool parse)
534547
}
535548
}
536549

537-
550+
free_rule_shared_data(rule, false);
538551
rule = rule->next;
539552
}
540553

@@ -567,6 +580,12 @@ API int adaptived_loop(struct adaptived_ctx * const ctx, bool parse)
567580
}
568581

569582
out:
583+
rule = ctx->rules;
584+
while (rule) {
585+
free_rule_shared_data(rule, true);
586+
rule = rule->next;
587+
}
588+
570589
pthread_mutex_unlock(&ctx->ctx_mutex);
571590

572591
return ret;

0 commit comments

Comments
 (0)