summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-02-16 16:30:40 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-02-16 16:30:40 +0100
commited9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590 (patch)
tree8b05ef6a4585b0d585f82c468cf92048a05f79ee
parentfc80d8b64672785b4d9c7127e852ca9bf19c9194 (diff)
downloadpcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.gz
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.bz2
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.xz
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.zip
1. Add python thread initialization to pcilib_init_py()
-Fix pcilib_script_run_func() work in multithread mode 2. pcilib_close() - Move free_py() code after free views to make view destructors work properly 3. Move script hash to pcilib_py_s 4. Move pcilib_get_logger() pcilib_get_logger_min_prio() and pcilib_get_logger_argument() declarations to error.h 5. Refactor pcilib_get_value_as_pyobject pcilib_set_value_from_pyobject to more unified form 6. Add more memory checks. Fix some string memory allocations. 7. Refactor pcilib_py_s member names. 8. Merge pcilib_script_read() and pcilib_script_write() to pcilib_script_run_func() 9. Update test_pywrap views scripts
-rw-r--r--pcilib/error.h14
-rw-r--r--pcilib/pci.c4
-rw-r--r--pcilib/pcilib.h15
-rw-r--r--pcilib/py.c180
-rw-r--r--pcilib/py.h12
-rw-r--r--pcilib/xml.c2
-rw-r--r--pywrap/pcipywrap.c11
-rw-r--r--views/transform.c8
-rw-r--r--xml/test_pywrap/test_prop2.py10
-rw-r--r--xml/test_pywrap/test_prop3.py9
10 files changed, 129 insertions, 136 deletions
diff --git a/pcilib/error.h b/pcilib/error.h
index a9f4c0b..95774e9 100644
--- a/pcilib/error.h
+++ b/pcilib/error.h
@@ -40,6 +40,20 @@ extern "C" {
void pcilib_log_message(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...);
void pcilib_log_vmessage(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, va_list va);
+/**
+ * Gets current logger function.
+ */
+pcilib_logger_t pcilib_get_logger();
+
+/**
+ * Gets current logger min priority.
+ */
+pcilib_log_priority_t pcilib_get_logger_min_prio();
+
+/**
+ * Gets current logger argument.
+ */
+void* pcilib_get_logger_argument();
#ifdef __cplusplus
}
diff --git a/pcilib/pci.c b/pcilib/pci.c
index c38097f..58ee4b0 100644
--- a/pcilib/pci.c
+++ b/pcilib/pci.c
@@ -306,8 +306,6 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx->event_plugin)
pcilib_plugin_close(ctx->event_plugin);
-
- pcilib_free_py(ctx);
if (ctx->locks.kmem)
pcilib_free_locking(ctx);
@@ -349,6 +347,8 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx->registers)
free(ctx->registers);
+
+ pcilib_free_py(ctx);
if (ctx->model)
free(ctx->model);
diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h
index 2458320..c32d1fb 100644
--- a/pcilib/pcilib.h
+++ b/pcilib/pcilib.h
@@ -263,21 +263,6 @@ extern "C" {
*/
int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg);
-/**
- * Gets current logger function.
- */
-pcilib_logger_t pcilib_get_logger();
-
-/**
- * Gets current logger min priority.
- */
-pcilib_log_priority_t pcilib_get_logger_min_prio();
-
-/**
- * Gets current logger argument.
- */
-void* pcilib_get_logger_argument();
-
/** public_api_global
* @}
*/
diff --git a/pcilib/py.c b/pcilib/py.c
index 20fa546..038dba6 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -11,24 +11,20 @@
#include "py.h"
#include "error.h"
-
-
-struct pcilib_py_s {
- PyObject *main_module;
- PyObject *global_dict;
- int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class
-};
-
typedef struct pcilib_script_s {
- char* script_name;
- PyObject *py_script_module; /**< PyModule object, contains script enviroment */
- PyObject *dict;
+ char* name;
+ PyObject *module; /**< PyModule object, contains script enviroment */
pcilib_access_mode_t mode;
UT_hash_handle hh;
} pcilib_script_s;
-struct pcilib_script_s *scripts = NULL;
+struct pcilib_py_s {
+ PyObject *main_module;
+ PyObject *global_dict;
+ int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class
+ struct pcilib_script_s *scripts;
+};
int pcilib_init_py(pcilib_t *ctx) {
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
@@ -37,6 +33,12 @@ int pcilib_init_py(pcilib_t *ctx) {
if(!Py_IsInitialized())
{
Py_Initialize();
+
+ //Since python is being initializing from c programm, it needs
+ //to initialize threads to works properly with c threads
+ PyEval_InitThreads();
+ PyEval_ReleaseLock();
+
ctx->py->py_initialized_inside = 1;
}
else
@@ -70,6 +72,8 @@ int pcilib_init_py(pcilib_t *ctx) {
free(model_path);
model_dir_added = 1;
}
+
+ ctx->py->scripts = NULL;
return 0;
}
@@ -237,53 +241,60 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
}
-void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val)
-{
+pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret)
+{
int err;
switch(val->type)
{
case PCILIB_TYPE_INVALID:
- pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)");
+ pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)");
+ if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED;
return NULL;
case PCILIB_TYPE_STRING:
- pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)");
+ pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)");
+ if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED;
return NULL;
case PCILIB_TYPE_LONG:
{
- long ret;
- ret = pcilib_get_value_as_int(ctx, val, &err);
+ long ret_val;
+ ret_val = pcilib_get_value_as_int(ctx, val, &err);
if(err)
{
- pcilib_error("Failed: pcilib_get_value_as_int (%i)", err);
+ if (ret) *ret = err;
return NULL;
}
- return (PyObject*)PyInt_FromLong((long) ret);
+
+ if (ret) *ret = 0;
+ return (PyObject*)PyInt_FromLong((long) ret_val);
}
case PCILIB_TYPE_DOUBLE:
{
- double ret;
- ret = pcilib_get_value_as_float(ctx, val, &err);
+ double ret_val;
+ ret_val = pcilib_get_value_as_float(ctx, val, &err);
if(err)
{
- pcilib_error("Failed: pcilib_get_value_as_int (%i)", err);
+ if (ret) *ret = err;
return NULL;
}
- return (PyObject*)PyFloat_FromDouble((double) ret);
+
+ if (ret) *ret = 0;
+ return (PyObject*)PyFloat_FromDouble((double) ret_val);
}
default:
- pcilib_warning("Invalid register output type (unknown)");
+ if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED;
+ pcilib_error("Invalid register output type (unknown)");
return NULL;
}
}
-int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val)
+int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal)
{
PyObject* pyVal = pyObjVal;
int err;
@@ -321,7 +332,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t
}
pcilib_script_s* module = NULL;
- HASH_FIND_STR( scripts, module_name, module);
+ HASH_FIND_STR( ctx->py->scripts, module_name, module);
if(module)
{
pcilib_warning("Python module %s is already in hash. Skip init step", module_name);
@@ -366,10 +377,16 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t
//Success. Create struct and initialize values
module = malloc(sizeof(pcilib_script_s));
- module->py_script_module = py_script_module;
- module->script_name = malloc(strlen(module_name));
- sprintf(module->script_name, "%s", module_name);
- module->dict = dict;
+ if (!module)
+ return PCILIB_ERROR_MEMORY;
+ module->module = py_script_module;
+ module->name = strdup(module_name);
+ if(!(module->name))
+ {
+ free(module);
+ return PCILIB_ERROR_MEMORY;
+ }
+ sprintf(module->name, "%s", module_name);
//Setting correct mode
@@ -380,15 +397,15 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t
mode[0] |= PCILIB_ACCESS_W;
module->mode = mode[0];
- HASH_ADD_STR( scripts, script_name, module);
+ HASH_ADD_STR( ctx->py->scripts, name, module);
return 0;
}
-int pcilib_py_free_script(char* module_name)
+int pcilib_py_free_script(pcilib_t *ctx,char* module_name)
{
pcilib_script_s *module;
- HASH_FIND_STR(scripts, module_name, module);
+ HASH_FIND_STR(ctx->py->scripts, module_name, module);
if(!module)
{
@@ -397,39 +414,51 @@ int pcilib_py_free_script(char* module_name)
return 0;
}
- if(module->script_name)
+ if(module->name)
{
- free(module->script_name);
- module->script_name = NULL;
+ free(module->name);
+ module->name = NULL;
}
- if(module->py_script_module)
+ if(module->module)
{
- //PyObject_Free(module->py_script_module);
- module->py_script_module = NULL;
+ module->module = NULL;
}
- HASH_DEL(scripts, module);
+ HASH_DEL(ctx->py->scripts, module);
free(module);
return 0;
}
-int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val)
-{
+int pcilib_script_run_func(pcilib_t *ctx, char* module_name,
+ const char* func_name, pcilib_value_t *val)
+{
+ int err;
pcilib_script_s *module;
- HASH_FIND_STR(scripts, module_name, module);
-
+ HASH_FIND_STR(ctx->py->scripts, module_name, module);
if(!module)
{
pcilib_error("Failed to find script module (%s) in hash", module_name);
return PCILIB_ERROR_NOTFOUND;
}
- int err;
-
PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()");
+ PyObject *input = pcilib_get_value_as_pyobject(ctx, val, &err);
+ if(err)
+ return err;
+
+ PyObject *py_func_name = PyUnicode_FromString(func_name);
+ PyObject *ret = PyObject_CallMethodObjArgs(module->module,
+ py_func_name,
+ input,
+ NULL);
+
+
+
+ Py_XDECREF(py_func_name);
+ Py_XDECREF(input);
PyGILState_Release(gstate);
+
if (!ret)
{
printf("Python script error: ");
@@ -437,55 +466,16 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val)
return PCILIB_ERROR_FAILED;
}
- err = pcilib_set_value_from_pyobject(ctx, ret, val);
- Py_XDECREF(ret);
-
- if(err)
- {
- pcilib_error("Failed to convert python script return value to internal type: %i", err);
- return err;
- }
- return 0;
-}
-
-int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val)
-{
- pcilib_script_s *module;
- HASH_FIND_STR(scripts, module_name, module);
-
- if(!module)
- {
- pcilib_error("Failed to find script module (%s) in hash", module_name);
- return PCILIB_ERROR_NOTFOUND;
- }
-
- PyObject *input = pcilib_get_value_as_pyobject(ctx, val);
- if(!input)
+ if(ret != Py_None)
{
- printf("Failed to convert input value to Python object");
- PyErr_Print();
- return PCILIB_ERROR_FAILED;
- }
- PyObject *func_name = PyUnicode_FromString("write_to_register");
+ err = pcilib_set_value_from_pyobject(ctx, val, ret);
+ Py_XDECREF(ret);
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module,
- func_name,
- input,
- NULL);
- PyGILState_Release(gstate);
-
- if (!ret)
- {
- printf("Python script error: ");
- PyErr_Print();
- return PCILIB_ERROR_FAILED;
+ if(err)
+ {
+ pcilib_error("Failed to convert python script return value to internal type: %i", err);
+ return err;
+ }
}
-
- //release objects
- Py_XDECREF(func_name);
- Py_XDECREF(ret);
- Py_XDECREF(input);
-
return 0;
}
diff --git a/pcilib/py.h b/pcilib/py.h
index 09e2b87..9703706 100644
--- a/pcilib/py.h
+++ b/pcilib/py.h
@@ -4,6 +4,7 @@
#include "pcilib.h"
typedef struct pcilib_py_s pcilib_py_t;
+typedef void pcilib_py_object;
#ifdef __cplusplus
extern "C" {
@@ -15,10 +16,9 @@ void pcilib_free_py(pcilib_t *ctx);
int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode);
-int pcilib_py_free_script(char* module_name);
-int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
-int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
-
+int pcilib_py_free_script(pcilib_t *ctx,char* module_name);
+int pcilib_script_run_func(pcilib_t *ctx, char* module_name,
+ const char* func_name, pcilib_value_t *val);
/*!
* \brief Converts pcilib_value_t to PyObject.
@@ -26,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
* \param val pointer to pcilib_value_t to convert
* \return PyObject, containing value. NULL with error message, sended to errstream.
*/
-void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val);
+pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *err);
/*!
@@ -36,7 +36,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val);
* \param val initialized polymorphic value
* \return 0 on success or memory error
*/
-int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val);
+int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal);
#ifdef __cplusplus
diff --git a/pcilib/xml.c b/pcilib/xml.c
index 4e95437..adca34e 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -600,7 +600,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
desc.write_to_reg = value;
if ((value)&&(*value)) mode |= PCILIB_ACCESS_W;
} else if (!strcasecmp(name, "script")) {
- desc.module = malloc(strlen(value));
+ desc.module = strdup(value);
sprintf(desc.module, "%s", value);
break;
}
diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c
index b1ee630..40dbdfc 100644
--- a/pywrap/pcipywrap.c
+++ b/pywrap/pcipywrap.c
@@ -127,7 +127,6 @@ PyObject* create_pcilib_instance(const char *fpga_device, const char *model)
pcilib_error("#E Failed pcilib_open(%s, %s)", fpga_device, model);
return NULL;
}
-
return PyCObject_FromVoidPtr((void*)ctx, close_pcilib_instance);
}
@@ -204,7 +203,7 @@ PyObject* read_register(const char *regname, const char *bank)
return NULL;
}
- return pcilib_get_value_as_pyobject(__ctx, &val);
+ return pcilib_get_value_as_pyobject(__ctx, &val, NULL);
}
/*!
@@ -228,7 +227,7 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank)
int err;
- err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal);
+ err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val);
if(err)
{
@@ -279,7 +278,7 @@ PyObject* get_property(const char *prop)
return NULL;
}
- return pcilib_get_value_as_pyobject(__ctx, &val);
+ return pcilib_get_value_as_pyobject(__ctx, &val, NULL);
}
/*!
@@ -299,7 +298,7 @@ PyObject* set_property(PyObject* val, const char *prop)
}
pcilib_value_t val_internal = {0};
- err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal);
+ err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val);
if(err)
{
pcilib_error("#E pcilib_set_value_from_pyobject, (error %i)", err);
@@ -339,7 +338,7 @@ void pcilib_pylist_append(PyObject* list, PyObject* value)
void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name)
{
- PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val);
+ PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val, NULL);
if(py_val)
pcilib_pydict_set_item(dict,
diff --git a/views/transform.c b/views/transform.c
index 75b95b2..24434e3 100644
--- a/views/transform.c
+++ b/views/transform.c
@@ -22,7 +22,8 @@ static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view
if (err) return err;
if(v->module)
- return pcilib_script_read(ctx, v->module, val);
+ return err = pcilib_script_run_func(ctx, v->module,
+ "read_from_register", val);
else
return pcilib_py_eval_string(ctx, v->read_from_reg, val);
}
@@ -40,7 +41,8 @@ static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *vie
if(v->module)
- err = pcilib_script_write(ctx, v->module, &val_copy);
+ err = pcilib_script_run_func(ctx, v->module,
+ "write_to_register", &val_copy);
else
err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
@@ -55,7 +57,7 @@ void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_descript
pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view);
if(v->module)
- pcilib_py_free_script(v->module);
+ pcilib_py_free_script(ctx, v->module);
}
pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_view_description_t *desc)
diff --git a/xml/test_pywrap/test_prop2.py b/xml/test_pywrap/test_prop2.py
index 69a2190..d7e10bc 100644
--- a/xml/test_pywrap/test_prop2.py
+++ b/xml/test_pywrap/test_prop2.py
@@ -1,8 +1,8 @@
import pcipywrap
+
+def read_from_register(value):
+ return pcipywrap.get_property('/test/prop3') / 2
-def read_from_register():
- return pcipywrap.get_property('/registers/fpga/reg1') / 2
-
-def write_to_register(value):
- pcipywrap.set_property(value*3, '/registers/fpga/reg1')
+def write_to_register(value):
+ pcipywrap.set_property(value*2, '/test/prop3')
diff --git a/xml/test_pywrap/test_prop3.py b/xml/test_pywrap/test_prop3.py
index c1300b3..9d33b63 100644
--- a/xml/test_pywrap/test_prop3.py
+++ b/xml/test_pywrap/test_prop3.py
@@ -1,4 +1,7 @@
-import os
+import pcipywrap
+
+def read_from_register(value):
+ return pcipywrap.get_property('/registers/fpga/reg1')
-def read_from_register():
- return 10;
+def write_to_register(value):
+ pcipywrap.set_property(value, '/registers/fpga/reg1')