Browse Source

Support dynamic loading of external libraries (pre-compiled user-provided functions)

master
Julian M. Kunkel 3 years ago
parent
commit
da2bdac120
  1. 27
      emulation/ngi.c
  2. 2
      emulation/ngi.h
  3. 25
      test/reduce-ngi-userlib.c
  4. 12
      test/reduce-ngi.c
  5. 4
      test/run.sh

27
emulation/ngi.c

@ -2,6 +2,7 @@
#include <assert.h>
#include <float.h>
#include <math.h>
#include <dlfcn.h>
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;
}

2
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

25
test/reduce-ngi-userlib.c

@ -0,0 +1,25 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include <float.h>
#include <math.h>
/*
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;
}

12
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;
}

4
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

Loading…
Cancel
Save