Browse Source

Add test to repository. Add GIL states to pcilib_set_value_from_pyobject

Vasilii Chernov 8 years ago
parent
commit
52eb7f4fb7
5 changed files with 221 additions and 0 deletions
  1. 4 0
      apps/CMakeLists.txt
  2. 94 0
      apps/test_multithread.c
  3. 3 0
      pcilib/py.c
  4. 1 0
      pywrap/CMakeLists.txt
  5. 119 0
      pywrap/test_pcipywrap.py

+ 4 - 0
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)
 

+ 94 - 0
apps/test_multithread.c

@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <pthread.h>
+#include "pcilib.h"
+#include <stdlib.h>
+
+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, &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 <device> <model> <register> <num_threads>\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;
+}

+ 3 - 0
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;
         

+ 1 - 0
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)

+ 119 - 0
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()
+