-
Notifications
You must be signed in to change notification settings - Fork 107
Add an extensible phase workload definition functionality. #54
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| AM_MAKEFLAGS=CC="$(CC)" | ||
| if SET_DLSCHED | ||
| SUBDIRS = libdl src | ||
| SUBDIRS = libdl src rtapp_function | ||
| else | ||
| SUBDIRS = src | ||
| SUBDIRS = src rtapp_function | ||
| endif | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "tasks" : { | ||
| "thread0" : { | ||
| "loop" : 3, | ||
| "phases" : { | ||
| "phase0" : { | ||
| "external_workload0" : { | ||
| "library_name" : "test_workload/test.so", | ||
| "main_method" : "test1" | ||
| }, | ||
| "external_workload1" : { | ||
| "library_name" : "test_workload/test.so", | ||
| "main_method" : "test1" | ||
| } | ||
| }, | ||
| "phase1" : { | ||
| "external_workload" : { | ||
| "library_name" : "test_workload/test.so", | ||
| "main_method" : "test2" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "global" : { | ||
| "calibration" : "CPU0", | ||
| "default_policy" : "SCHED_OTHER", | ||
| "pi_enabled" : false, | ||
| "lock_pages" : false, | ||
| "logdir" : "./", | ||
| "log_basename" : "rt-app9", | ||
| "ftrace" : false, | ||
| "gnuplot" : false | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| SOURCE = $(wildcard */*.c) | ||
| LIBRARIES = $(SOURCE:.c=.so) | ||
|
|
||
| .PHONY: all clean | ||
|
|
||
| all: $(LIBRARIES) | ||
|
|
||
| clean: | ||
| echo "cleaning libraries" | ||
| rm -f */*.so | ||
|
|
||
| %.so : %.c | ||
| @echo "*** building external workload $(<:.c=)" | ||
| $(CC) $^ -rdynamic -shared -fPIC -o $@ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #include <stdio.h> | ||
|
|
||
| volatile int testVar = 0; | ||
|
|
||
| int test1() { | ||
|
|
||
| testVar++; | ||
| printf("first test %d\n", testVar); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmm, this breaks rt-app log_* output format. :-/
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are the external workloads generally expected to call printf or do any logging for that matter? Is this really required? |
||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| int test2() { | ||
|
|
||
| printf("second test %d\n", testVar); | ||
|
|
||
| return 0; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| #include <string.h> | ||
| #include <sys/stat.h> | ||
| #include <getopt.h> | ||
| #include <limits.h> | ||
| #include <errno.h> | ||
|
|
||
| #include "rt-app_utils.h" | ||
| #include "rt-app_parse_config.h" | ||
|
|
||
| char help_usage[] = \ | ||
|
|
@@ -60,11 +63,55 @@ struct option long_args[] = { | |
| {0, 0, 0, 0} | ||
| }; | ||
|
|
||
| static char* main_install_path = NULL; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to initialize this to NULL.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed initialisation. |
||
|
|
||
| char const* get_shared_library_base_path() | ||
| { | ||
| return main_install_path; | ||
| } | ||
|
|
||
| void | ||
| parse_command_line(int argc, char **argv, rtapp_options_t *opts) | ||
| { | ||
| struct stat config_file_stat; | ||
| int c; | ||
| int full_path_len; | ||
| int main_install_path_len; | ||
|
|
||
| const char shared_lib_dir_name[] = "/../rtapp_function/"; | ||
|
|
||
| /* get the rt-app base directory full name */ | ||
| char* full_path = malloc(PATH_MAX); | ||
| int index; | ||
| int return_snprintf = 0; | ||
|
|
||
| /* get the program invocation string and extract the base directory content */ | ||
| if (!realpath(argv[0], full_path)) { | ||
| log_error("failed to get rt-app base path: %s", strerror(errno)); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| for(index=strlen(full_path)-1; index>0; index--) { | ||
| if(full_path[index]=='/') { | ||
| full_path[index]='\0'; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| full_path_len = strlen(full_path); | ||
|
|
||
| main_install_path_len = full_path_len + sizeof(shared_lib_dir_name) + 1; | ||
| main_install_path = malloc(main_install_path_len); | ||
| if (!main_install_path) { | ||
| log_error("failed to allocate %d bytes: %s", main_install_path_len, strerror(errno)); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| return_snprintf = snprintf(main_install_path, main_install_path_len,"%s%s", full_path, shared_lib_dir_name); | ||
| if(return_snprintf >= main_install_path_len || return_snprintf < 0) { | ||
| log_error("failed to compose install path\n"); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| while (1) { | ||
| c = getopt_long(argc, argv, "hv", long_args, 0); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,8 +26,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| #include <string.h> | ||
| #include <fcntl.h> | ||
| #include <json-c/json.h> | ||
| #include <dlfcn.h> | ||
|
|
||
| #include "rt-app_utils.h" | ||
| #include "rt-app_args.h" | ||
| #include "rt-app_parse_config.h" | ||
|
|
||
| #define PFX "[json] " | ||
|
|
@@ -363,6 +365,57 @@ static char* create_unique_name(char *tmp, int size, const char* ref, long tag) | |
| return tmp; | ||
| } | ||
|
|
||
| void initialise_external_library(rtapp_resource_t *rdata) | ||
| { | ||
| void *library_handle; | ||
| void *symbol; | ||
| char const* shared_library_dir_name = NULL; | ||
| char *full_library_name = NULL; | ||
|
|
||
| char *library_name = rdata->res.external_workload.library_name; | ||
| int base_path_len = 0; | ||
| int lib_name_len = 0; | ||
| int full_library_name_length = 0; | ||
| int return_snprintf; | ||
|
|
||
| shared_library_dir_name = get_shared_library_base_path(); | ||
| if (!shared_library_dir_name) { | ||
| log_error("failed to obtain shared library directory\n"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exit(EXIT_FAILURE)?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| base_path_len = strlen(shared_library_dir_name); | ||
| lib_name_len = strlen(library_name); | ||
| full_library_name_length = base_path_len + lib_name_len +1; | ||
|
|
||
| full_library_name = malloc(full_library_name_length); | ||
| if (!full_library_name) { | ||
| log_error("failed to allocate memory for library name\n"); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| return_snprintf = snprintf(full_library_name, full_library_name_length, "%s%s", shared_library_dir_name, library_name); | ||
| if(return_snprintf >= full_library_name_length || return_snprintf < 0) { | ||
| log_error("failed to compose the full library name\n"); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| library_handle = dlopen(full_library_name, RTLD_NOW | RTLD_LOCAL); | ||
| if(library_handle == NULL) { | ||
| log_info(PIN2 "failed to open shared library: %s\n", dlerror()); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
| free(full_library_name); | ||
|
|
||
| symbol = dlsym(library_handle, rdata->res.external_workload.symbol_name); | ||
| if(!symbol) { | ||
| log_info(PIN2 "failed to open obtain symbol: %s\n", dlerror()); | ||
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| rdata->res.external_workload.workload = symbol; | ||
| } | ||
|
|
||
| static void | ||
| parse_thread_event_data(char *name, struct json_object *obj, | ||
| event_data_t *data, rtapp_options_t *opts, long tag) | ||
|
|
@@ -517,6 +570,36 @@ parse_thread_event_data(char *name, struct json_object *obj, | |
| return; | ||
| } | ||
|
|
||
| if (!strncmp(name, "external_workload", strlen("external_workload"))) { | ||
|
|
||
| data->type = rtapp_external_workload; | ||
|
|
||
| ref = json_object_get_string(obj); | ||
|
|
||
| i = add_resource_data(name, rtapp_external_workload, opts); | ||
|
|
||
| data->res = i; | ||
| rdata = &(opts->resources[data->res]); | ||
|
|
||
| /* | ||
| * Get the name of the shared library as well as | ||
| * the optional method name | ||
| */ | ||
| rdata->res.external_workload.library_name = get_string_value_from(obj, "library_name", FALSE, ""); | ||
|
|
||
| tmp = get_string_value_from(obj, "main_method", TRUE, "workload"); | ||
| rdata->res.external_workload.symbol_name = tmp; | ||
|
|
||
| log_info(PIN2 "type %d target %s [%d] lib name %s, workload %s\n", | ||
| data->type, rdata->name, rdata->index, rdata->res.external_workload.library_name, | ||
| rdata->res.external_workload.symbol_name); | ||
|
|
||
| /* Load the symbol in the dynamic library */ | ||
| initialise_external_library(rdata); | ||
|
|
||
| return; | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
|
|
||
| if (!strncmp(name, "timer", strlen("timer"))) { | ||
|
|
||
| tmp = get_string_value_from(obj, "ref", TRUE, "unknown"); | ||
|
|
@@ -631,6 +714,7 @@ static char *events[] = { | |
| "iorun", | ||
| "yield", | ||
| "barrier", | ||
| "external_workload", | ||
| NULL | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, I'm wondering if pulling "random" code into rt-app sources is really a good idea.
I guess we are basically subscribing to maintaining all the snippets we import.. :-(
Alternatives?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, this should be mostly a mechanism to allow for random code to be used as rt-app phases. Only very select and generic code snippets should be committed to rt-app. The current workload which is part of the PR has the purpose of showcasing that the mechanism works for complex workloads, it should not be part of the PR when it hypothetically gets merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm OK. I wonder what's the best way to make life easy for potential users of this new feature, though. I guess having a very simple example in the repo would certainly help. And I also guess adding substantial documentation to tutorial.txt should help as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
created a simple workload which just prints an integer. The workload has two methods that behave differently with respect to the integer increment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added documentation to doc/tutorial.txt detailing the external_workload event.