From 52eb7f4fb76ddf99dedf44332aae7af4df76ab36 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 18:13:36 +0100 Subject: Add test to repository. Add GIL states to pcilib_set_value_from_pyobject --- apps/CMakeLists.txt | 4 ++ apps/test_multithread.c | 94 +++++++++++++++++++++++++++++++++++++ pcilib/py.c | 3 ++ pywrap/CMakeLists.txt | 1 + pywrap/test_pcipywrap.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+) create mode 100644 apps/test_multithread.c create mode 100755 pywrap/test_pcipywrap.py diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 4524db4..2a1471c 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -7,6 +7,10 @@ link_directories( ${CMAKE_BINARY_DIR}/pcilib ) +find_package (Threads) +add_executable(test_multithread test_multithread.c) +target_link_libraries (test_multithread pcilib ${CMAKE_THREAD_LIBS_INIT}) + add_executable(xilinx xilinx.c) target_link_libraries(xilinx pcilib rt) diff --git a/apps/test_multithread.c b/apps/test_multithread.c new file mode 100644 index 0000000..cad4cd9 --- /dev/null +++ b/apps/test_multithread.c @@ -0,0 +1,94 @@ +#include +#include +#include "pcilib.h" +#include + +const char* prop = "/registers/fpga/reg1"; +char* reg; +int stop = 0; + +void *get_prop(void *arg) +{ + pcilib_t *ctx = (pcilib_t*)arg; + + while(!stop) + { + int err; + pcilib_value_t val = {0}; + err = pcilib_get_property(ctx, prop, &val); + if(err) + { + printf("err pcilib_read_register\n"); + return NULL; + } + long value = pcilib_get_value_as_int(ctx, &val, &err); + pcilib_clean_value(ctx, &val); + if(err) + { + printf("err pcilib_get_value_as_int\n"); + return NULL; + } + printf("reg = %i\n", value); + } + return NULL; +} + +void *read_reg(void *arg) +{ + pcilib_t *ctx = (pcilib_t*)arg; + + while(!stop) + { + int err; + pcilib_register_value_t reg_val = {0}; + pcilib_value_t val = {0}; + + err = pcilib_read_register(ctx, NULL, reg, ®_val); + + if(err) + { + printf("err pcilib_read_register\n"); + return NULL; + } + err = pcilib_set_value_from_register_value(ctx, &val, reg_val); + if(err) + { + printf("err pcilib_set_value_from_register_value\n"); + return NULL; + } + long value = pcilib_get_value_as_int(ctx, &val, &err); + pcilib_clean_value(ctx, &val); + if(err) + { + printf("err pcilib_get_value_as_int\n"); + return NULL; + } + printf("reg = %i\n", value); + } + return NULL; +} + +int main(int argc, char *argv[]) +{ + if (argc < 5) { + printf("Usage:\n\t\t%s \n", argv[0]); + exit(0); + } + + reg = argv[3]; + int threads = atoi( argv[4] ); + + pcilib_t *ctx = pcilib_open(argv[1], argv[2]); + int err; + pcilib_value_t val = {0}; + + for(int i = 0; i < threads; i++) + { + pthread_t pth; + pthread_create(&pth, NULL, read_reg, ctx); + } + + getchar(); + stop = 1; + return 0; +} diff --git a/pcilib/py.c b/pcilib/py.c index 372d475..a288043 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -347,6 +347,7 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py PyObject* pyVal = pyObjVal; int err; + PyGILState_STATE gstate = PyGILState_Ensure(); if(PyInt_Check(pyVal)) { err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); @@ -359,9 +360,11 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); else { + PyGILState_Release(gstate); pcilib_error("Invalid input. Input type should be int, float or string."); return PCILIB_ERROR_NOTSUPPORTED; } + PyGILState_Release(gstate); if(err) return err; diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index d4d75d1..4592c9a 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -19,3 +19,4 @@ SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c) SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) configure_file(server.py server.py) +configure_file(test_pcipywrap.py test_pcipywrap.py) diff --git a/pywrap/test_pcipywrap.py b/pywrap/test_pcipywrap.py new file mode 100755 index 0000000..257b4a5 --- /dev/null +++ b/pywrap/test_pcipywrap.py @@ -0,0 +1,119 @@ +import threading +import pcipywrap +import random +import os +import json +import requests +import time + +class test_pcipywrap(): + def __init__(self, device, model, num_threads = 150, + write_percentage = 0.1, register = 'test_prop2', + server_host = 'http://localhost', server_port = 12412, + server_message_delay = 0): + #initialize enviroment variables + if not 'APP_PATH' in os.environ: + APP_PATH = '' + file_dir = os.path.dirname(os.path.abspath(__file__)) + APP_PATH = str(os.path.abspath(file_dir + '/../..')) + os.environ["APP_PATH"] = APP_PATH + + if not 'PCILIB_MODEL_DIR' in os.environ: + os.environ['PCILIB_MODEL_DIR'] = os.environ["APP_PATH"] + "/xml" + if not 'LD_LIBRARY_PATH' in os.environ: + os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" + + random.seed() + #create pcilib_instance + self.pcilib = pcipywrap.Pcipywrap(device, model) + self.num_threads = num_threads + self.write_percentage = write_percentage + self.register = register + self.server_message_delay = server_message_delay + self.server_port = server_port + self.server_host = server_host + + def testThreadSafeReadWrite(self): + def threadFunc(): + if random.randint(0, 100) >= (self.write_percentage * 100): + ret = self.pcilib.get_property('/test/prop2') + print self.register, ':', ret + del ret + else: + val = random.randint(0, 65536) + print 'set value:', val + self.pcilib.write_register(val, self.register) + try: + while(1): + thread_list = [threading.Thread(target=threadFunc) for i in range(0, self.num_threads)] + for i in range(0, self.num_threads): + thread_list[i].start() + for i in range(0, self.num_threads): + thread_list[i].join() + print 'cycle done' + except KeyboardInterrupt: + print 'testing done' + pass + + def testMemoryLeak(self): + try: + while(1): + #print self.pcilib.create_pcilib_instance('/dev/fpga0','test_pywrap') + + print self.pcilib.get_property_list('/test') + print self.pcilib.get_register_info('test_prop1') + #print self.pcilib.get_registers_list(); + + #print self.pcilib.read_register('reg1') + #print self.pcilib.write_register(12, 'reg1') + + #print self.pcilib.get_property('/test/prop2') + #print self.pcilib.set_property(12, '/test/prop2') + except KeyboardInterrupt: + print 'testing done' + pass + + def testServer(self): + url = str(self.server_host + ':' + str(self.server_port)) + headers = {'content-type': 'application/json'} + payload =[{'com': 'open', 'data2' : '12341'}, + #{'command': 'open', 'device' : '/dev/fpga0', 'model': 'test_pywrap'}, + {'command': 'help'}, + {'command': 'get_registers_list'}, + {'command': 'get_register_info', 'reg': 'reg1'}, + {'command': 'get_property_list'}, + {'command': 'read_register', 'reg': 'reg1'}, + {'command': 'write_register', 'reg': 'reg1'}, + {'command': 'get_property', 'prop': '/test/prop2'}, + {'command': 'set_property', 'prop': '/test/prop2'}] + + def sendRandomMessage(): + message_number = random.randint(1, len(payload) - 1) + print 'message number: ', message_number + payload[message_number]['value'] = random.randint(0, 65535) + r = requests.get(url, data=json.dumps(payload[message_number]), headers=headers) + print json.dumps(r.json(), sort_keys=True, indent=4, separators=(',', ': ')) + + try: + r = requests.get(url, data=json.dumps(payload[1]), headers=headers) + print json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': ')) + + while(1): + time.sleep(self.server_message_delay) + thread_list = [threading.Thread(target=sendRandomMessage) for i in range(0, self.num_threads)] + for i in range(0, self.num_threads): + thread_list[i].start() + for i in range(0, self.num_threads): + thread_list[i].join() + print 'cycle done' + + except KeyboardInterrupt: + print 'testing done' + pass + +if __name__ == '__main__': + lib = test_pcipywrap('/dev/fpga0','test_pywrap', num_threads = 150, + write_percentage = 0.1, register = 'test_prop2',server_host = 'http://localhost', server_port = 12412, + server_message_delay = 0) + lib.testThreadSafeReadWrite() + -- cgit v1.2.3