Skip to content

Conversation

@jmarinho
Copy link

@jmarinho jmarinho commented Aug 29, 2018

Allow phases to execute workloads from shared objects present in the rtapp_function/ directory.
This allows for a more straightforward integration of external workloads with rt-app, ideally it makes it a less cumbersome exercise. It would allow, for instance, NEON kernels or any other particular code to be used in rt-app more easily. The workloads can be easily contributed back to the rt-app repo and will not contribute to rt-app base src pollution since they are fairly isolated.

@jlelli
Copy link
Contributor

jlelli commented Sep 13, 2018

Got the following while compiling (gcc (GCC) 8.1.1)

$ make
Making all in libdl
make[1]: Entering directory '/home/juri/work/scheduler-tools/rt-app/libdl'
gcc -DHAVE_CONFIG_H -I. -I../src     -g -O2 -MT dl_syscalls.o -MD -MP -MF .deps/dl_syscalls.Tpo -c -o dl_syscalls.o dl_syscalls.c
mv -f .deps/dl_syscalls.Tpo .deps/dl_syscalls.Po
rm -f libdl.a
ar cru libdl.a dl_syscalls.o
ranlib libdl.a
make[1]: Leaving directory '/home/juri/work/scheduler-tools/rt-app/libdl'
Making all in src
make[1]: Entering directory '/home/juri/work/scheduler-tools/rt-app/src'
make  all-am
make[2]: Entering directory '/home/juri/work/scheduler-tools/rt-app/src'
gcc -DHAVE_CONFIG_H -I.  -I./../libdl/   -g -O2 -MT rt-app_utils.o -MD -MP -MF .deps/rt-app_utils.Tpo -c -o rt-app_utils.o rt-app_utils.c
mv -f .deps/rt-app_utils.Tpo .deps/rt-app_utils.Po
gcc -DHAVE_CONFIG_H -I.  -I./../libdl/   -g -O2 -MT rt-app_args.o -MD -MP -MF .deps/rt-app_args.Tpo -c -o rt-app_args.o rt-app_args.c
mv -f .deps/rt-app_args.Tpo .deps/rt-app_args.Po
gcc -DHAVE_CONFIG_H -I.  -I./../libdl/   -g -O2 -MT rt-app.o -MD -MP -MF .deps/rt-app.Tpo -c -o rt-app.o rt-app.c
mv -f .deps/rt-app.Tpo .deps/rt-app.Po
gcc -DHAVE_CONFIG_H -I.  -I./../libdl/   -g -O2 -MT rt-app_parse_config.o -MD -MP -MF .deps/rt-app_parse_config.Tpo -c -o rt-app_parse_config.o rt-app_parse_config.c
rt-app_parse_config.c: In function ‘initialise_external_library’:
rt-app_parse_config.c:385:2: warning: ‘strncpy’ specified bound depends on the length of the source argument [-Wstringop-overflow=]
  strncpy(full_library_name, shared_library_dir_name, base_path_len);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rt-app_parse_config.c:380:22: note: length computed here
  int base_path_len = strlen(shared_library_dir_name);
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mv -f .deps/rt-app_parse_config.Tpo .deps/rt-app_parse_config.Po
/bin/sh ../libtool  --tag=CC   --mode=link gcc  -g -O2   -o rt-app rt-app_utils.o rt-app_args.o rt-app.o rt-app_parse_config.o  ../libdl/libdl.a -ljson-c -ldl -lrt -lm -lpthread
libtool: link: gcc -g -O2 -o rt-app rt-app_utils.o rt-app_args.o rt-app.o rt-app_parse_config.o  ../libdl/libdl.a -ljson-c -ldl -lrt -lm -lpthread
make[2]: Leaving directory '/home/juri/work/scheduler-tools/rt-app/src'
make[1]: Leaving directory '/home/juri/work/scheduler-tools/rt-app/src'
Making all in rtapp_function
make[1]: Entering directory '/home/juri/work/scheduler-tools/rt-app/rtapp_function'
*** building external workload fpBench/fp
gcc fpBench/fp.c  -rdynamic -shared -fPIC -o fpBench/fp.so
make[1]: Leaving directory '/home/juri/work/scheduler-tools/rt-app/rtapp_function'
make[1]: Entering directory '/home/juri/work/scheduler-tools/rt-app'
make[1]: Nothing to be done for 'all-am'.
make[1]: Leaving directory '/home/juri/work/scheduler-tools/rt-app'

Please fix.

@jmarinho
Copy link
Author

fixed the warning at rt-app_parse_config.c:385 .

@jlelli
Copy link
Contributor

jlelli commented Sep 14, 2018

Unfortunately this still has problems:

rt-app_parse_config.c: In function ‘initialise_external_library’:
rt-app_parse_config.c:386:2: warning: ‘strncpy’ specified bound depends on the length of the source argument [-Wstringop-overflow=]
  strncpy(full_library_name, shared_library_dir_name, full_library_name_length);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rt-app_parse_config.c:380:22: note: length computed here
  int base_path_len = strlen(shared_library_dir_name);
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

AFAIK snprintf is actually to prefer to strncpy (e.g., https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/ - Handling truncation when it occurs)

@jmarinho jmarinho force-pushed the master branch 3 times, most recently from e75c1b7 to 4150d87 Compare September 17, 2018 16:17
@jmarinho
Copy link
Author

Removed strncpy and substituted those code spinets with snprintf. Gcc 8.1 with -Wall does not issue the warnings you were referring to. Which C flags are you using in the compilation?

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to produce any sort of logs or numbers.
How is this supposed to be used? How the user get to know what happended or how the external workload performed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the example a bit more complex so as to show a potential user how to manage the functionality. The external_workload should behave as a regular event. The execution of the external workload produces debug output (when that log level is selected) in the rt-app.c

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved to doc/examples/tutorial/example9.json

Also please include a global section like the following

       "global" : {
                "calibration" : "CPU0",
                "default_policy" : "SCHED_OTHER",
                "pi_enabled" : false,
                "lock_pages" : false,
                "logdir" : "./",
                "log_basename" : "rt-app9",
                "ftrace" : false,
                "gnuplot" : false,
        }

and indent tasks as for the other examples

if (!realpath(argv[0], full_path))
{
log_error("failed to get rt-app base path: %s", strerror(errno));
exit(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use exit(EXIT_FAILURE) here and where appropriate.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

exit(0);
}

snprintf(main_install_path,main_install_path_len,"%s%s", full_path, shared_lib_dir_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess we should check for errors?
Also please align properly with a tab.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


/*if (!json_object_is_type(obj, json_type_string))
goto unknown_event;
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed comment

* Get the name of the shared library as well as
* the optional method name
*/
char *tmp = get_string_value_from(obj, "library_name", FALSE, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need the tmp variable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed tmp declaration

char const* shared_library_dir_name = get_shared_library_base_path();
if (!shared_library_dir_name)
{
log_error("failed to obtain shared library directory\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exit(EXIT_FAILURE)?
Also please don't mix declarations and code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return tmp;
}

void initialise_external_library(rtapp_resource_t *library_struct)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simply rdata maybe (as it contains more data that the one strictly associated with the library)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having difficulties understanding what the comment refers to. Can you please rephrase?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, simply a huge nitpick.. I'd s/library_struct/rdata/ :-)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed library_struct to rdata


char *full_library_name = malloc(full_library_name_length);

snprintf(full_library_name, full_library_name_length, "%s%s", shared_library_dir_name, library_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for errors.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

src/rt-app.c Outdated
break;
case rtapp_external_workload:
rdata->res.external_workload.workload();
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align with tabs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Adapted from Press et al., "Numerical Recipes in C".
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you write this yourself or is the code taken from some other source?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an floating point benchmark obtained from some external source. It was uploaded with the intent of showcasing that complex code can be ran as a rt-app phase. This probably should not be kept as part of the PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed fp benchmark.

@@ -0,0 +1,14 @@
SOURCE = $(wildcard */*.c)
Copy link
Contributor

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?

Copy link
Author

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.

Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Author

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.

@jmarinho jmarinho force-pushed the master branch 7 times, most recently from d3d2c4f to 53469a7 Compare September 21, 2018 16:06
{0, 0, 0, 0}
};

static char* main_install_path = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to initialize this to NULL.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed initialisation.

int full_path_len;
int main_install_path_len;

static const char shared_lib_dir_name[] = "/../rtapp_function/";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why static?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed static.

/* get the rt-app base directory full name */
char* full_path = malloc(PATH_MAX);
int index;
int return_snprintf = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the indentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


/* get the program invocation string and extract the base directory content */
if (!realpath(argv[0], full_path))
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick!
Not sure we enforce this everywhere, but I like better parenthesis to be aligned with if and for statements.

if (condition) {
}

for (;;) {
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved curlies on all relevant lines.

exit(EXIT_FAILURE);
}

return_snprintf = snprintf(main_install_path, main_install_path_len,"%s%s", full_path, shared_lib_dir_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

int test1() {

testVar++;
printf("first test %d\n", testVar);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm, this breaks rt-app log_* output format. :-/
Wonder if we can make that available to external workloads and actually enforce that is used?

Copy link
Author

Choose a reason for hiding this comment

The 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?

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved to doc/examples/tutorial/example9.json

Also please include a global section like the following

       "global" : {
                "calibration" : "CPU0",
                "default_policy" : "SCHED_OTHER",
                "pi_enabled" : false,
                "lock_pages" : false,
                "logdir" : "./",
                "log_basename" : "rt-app9",
                "ftrace" : false,
                "gnuplot" : false,
        }

and indent tasks as for the other examples

doc/tutorial.txt Outdated
* yield: String. Calls pthread_yield(), freeing the CPU for other tasks. This has a
special meaning for SCHED_DEADLINE tasks. String can be empty.

* external_workload: Executes a function declared in a shared library. The shared
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add type (e.g. sync event).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

doc/tutorial.txt Outdated
special meaning for SCHED_DEADLINE tasks. String can be empty.

* external_workload: Executes a function declared in a shared library. The shared
libraries are stored at rtapp_function/<workload base directory>/ .For each c file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick. Space after full stop.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

doc/tutorial.txt Outdated
* external_workload: Executes a function declared in a shared library. The shared
libraries are stored at rtapp_function/<workload base directory>/ .For each c file
present in the workload base directory a shared library is compiled. The external_workload
must is defined, in the rt-app taskset definition, by two fields:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/must//

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Add support for phases declared as "external_workload".
Execute the  method previously loaded from the shared
object of an "external_workload" phase.
New external test workload added to rtapp_function/test.
The json example usage is at doc/examples/shared_object_workload.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants