From da2bdac120d36e286d71290486201a13badb64a7 Mon Sep 17 00:00:00 2001 From: "Julian M. Kunkel" Date: Sun, 25 Aug 2019 11:01:04 +0100 Subject: [PATCH] Support dynamic loading of external libraries (pre-compiled user-provided functions) --- emulation/ngi.c | 27 +++++++++++++++++++++++++++ emulation/ngi.h | 2 ++ test/reduce-ngi-userlib.c | 25 +++++++++++++++++++++++++ test/reduce-ngi.c | 12 +++++++++++- test/run.sh | 4 +++- 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/reduce-ngi-userlib.c diff --git a/emulation/ngi.c b/emulation/ngi.c index 1f49261..7ed22d0 100644 --- a/emulation/ngi.c +++ b/emulation/ngi.c @@ -2,6 +2,7 @@ #include #include #include +#include int server_reduce(FILE * file, ngi_op_t op, ngi_type_t type, void * out_buff, size_t off, size_t size){ fseek(file, off, SEEK_SET); @@ -31,3 +32,29 @@ int server_reduce_any_func(FILE * file, void (*func)(int8_t * data, void * out_b free(data); return 0; } + +int server_reduce_any_func_lib(FILE * file, char const * libname, char const * funcname, void * out_buff, size_t max_out_data_size, size_t off, size_t size){ + void *handle; + handle = dlopen(libname, RTLD_LAZY); + if(! handle){ + printf("Error %s\n", dlerror()); + return 1; + } + + fseek(file, off, SEEK_SET); + + void (*func)(int8_t * data, void * out_buff, size_t off, size_t size) = dlsym(handle, funcname); + if(! func){ + printf("Error %s\n", dlerror()); + dlclose(handle); + return 1; + } + + int8_t * data = malloc(size); + fread(data, size, 1, file); + func(data, out_buff, off, size); + free(data); + + dlclose(handle); + return 0; +} diff --git a/emulation/ngi.h b/emulation/ngi.h index d6cbdda..5406dde 100644 --- a/emulation/ngi.h +++ b/emulation/ngi.h @@ -26,5 +26,7 @@ int server_reduce(FILE * file, ngi_op_t op, ngi_type_t type, void * out_buff, si */ int server_reduce_any_func(FILE * file, void (*func)(int8_t * data, void * out_buff, size_t off, size_t size), void * out_buff, size_t max_out_data_size, size_t off, size_t size); +int server_reduce_any_func_lib(FILE * file, char const * libname, char const * funcname, void * out_buff, size_t max_out_data_size, size_t off, size_t size); + #endif diff --git a/test/reduce-ngi-userlib.c b/test/reduce-ngi-userlib.c new file mode 100644 index 0000000..bd69a2e --- /dev/null +++ b/test/reduce-ngi-userlib.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/* + Extra user library provided + */ + +void reduce_minmax_func_external(int8_t * data_i, void * out_buff, size_t off, size_t size){ + float * outf = (float*) out_buff; + float mi = outf[0]; + float mx = outf[1]; + float * data = (float*) data_i; + for(size_t i=0; i < size/sizeof(float); i++){ + mx = data[i] > mx ? data[i]: mx; + mi = data[i] < mi ? data[i]: mi; + } + outf[0] = mi; + outf[1] = mx; +} diff --git a/test/reduce-ngi.c b/test/reduce-ngi.c index 31c6fd9..3c7d8ca 100644 --- a/test/reduce-ngi.c +++ b/test/reduce-ngi.c @@ -45,7 +45,7 @@ void reduce_minmax_func(int8_t * data_i, void * out_buff, size_t off, size_t siz outf[1] = mx; } -// alternative using an external function +// alternative using an internal function void reduce_data_func(int size){ FILE * file = fopen("data.bin", "rb"); float mx; @@ -59,10 +59,20 @@ void reduce_data_func(int size){ fclose(file); } +// alternative using an external library function shipped a s lib +void reduce_data_func_lib(int size){ + FILE * file = fopen("data.bin", "rb"); + float minmax[2] = {INFINITY, -INFINITY}; + server_reduce_any_func_lib(file, "./libreduce-ngi-userlib.so", "reduce_minmax_func_external", minmax, 2* sizeof(float), 0, size*sizeof(float)); + printf("Using the external library libreduce-ngi-userlib.so provided by the user: Min/Max: %f - %f\n", minmax[0], minmax[1]); + fclose(file); +} + int main(){ int size = 100; reduce_data(size); reduce_data_func(size); + reduce_data_func_lib(size); return 0; } diff --git a/test/run.sh b/test/run.sh index 2895cf1..222e260 100755 --- a/test/run.sh +++ b/test/run.sh @@ -7,9 +7,11 @@ gcc -Wall -Wextra reduce-traditional.c -o reduce-traditional -g3 # Build NGI lib -gcc -Wall -Wextra ../emulation/ngi.c -shared -fpic -o libngi.so -g3 -I../emulation/ +gcc -Wall -Wextra ../emulation/ngi.c -shared -fpic -o libngi.so -g3 -I../emulation/ -ldl # Build client application gcc -Wall -Wextra reduce-ngi.c -o reduce-ngi -g3 -I../emulation/ -L. -l ngi -Wl,-rpath=$PWD +# Build extra user library +gcc -Wall -Wextra reduce-ngi-userlib.c -shared -fpic -o libreduce-ngi-userlib.so -g3 echo "Data generation" ./data-gen