From c79d43273769d88f7129a3d53c80b85a6dc1946c Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 3 Mar 2016 15:38:32 +0100 Subject: 1. Pcipywrap: add persistent locking wrappings 2. html-server: - add scripts tab - change tab view to jQuery tabs --- pcilib/py.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pcilib') diff --git a/pcilib/py.c b/pcilib/py.c index 833532e..bec7d08 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -130,7 +130,7 @@ int pcilib_init_py(pcilib_t *ctx) { // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads PyEval_InitThreads(); PyEval_ReleaseLock(); - ctx->py->finalyze = 1; + ctx->py->finalyze = 1; } ctx->py->main_module = PyImport_AddModule("__parser__"); -- cgit v1.2.3 From 4b4dc3c70ef19a29386c2b3e8284687851094eb9 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 4 Mar 2016 09:31:42 +0100 Subject: Fix python3 initialization from pcilib_t --- pcilib/py.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 132 insertions(+), 18 deletions(-) (limited to 'pcilib') diff --git a/pcilib/py.c b/pcilib/py.c index bec7d08..94d7ed8 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -2,6 +2,11 @@ #ifdef HAVE_PYTHON # include + +#if PY_MAJOR_VERSION >= 3 +#include +#endif /* PY_MAJOR_VERSION >= 3 */ + #endif /* HAVE_PYTHON */ #include @@ -27,12 +32,24 @@ struct pcilib_script_s { UT_hash_handle hh; /**< hash */ }; +#if PY_MAJOR_VERSION >= 3 +typedef struct pcilib_py_s_thread_control { + pthread_t pth; + pthread_cond_t cond_finished; + pthread_mutex_t cond_finished_lock; +} pcilib_py_s_thread_control; +#endif /* PY_MAJOR_VERSION < 3 */ + struct pcilib_py_s { int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */ PyObject *main_module; /**< Main interpreter */ PyObject *global_dict; /**< Dictionary of main interpreter */ PyObject *pcilib_pywrap; /**< pcilib wrapper module */ pcilib_script_t *script_hash; /**< Hash with loaded scripts */ + +#if PY_MAJOR_VERSION >= 3 + pcilib_py_s_thread_control *thr_ctl; /**< Controller for Python main loop thread for Python 3 */ +#endif /* PY_MAJOR_VERSION < 3 */ }; #endif /* HAVE_PYTHON */ @@ -55,7 +72,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag PyErr_NormalizeException(&pytype, &pyval, &pytraceback); if (pyval) pystr = PyObject_Str(pyval); -# if PY_MAJOR_VERSION >= 3 +#if PY_MAJOR_VERSION >= 3 if (pytype) { if (PyUnicode_Check(pytype)) type = PyUnicode_AsUTF8(pytype); @@ -65,7 +82,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag if (pystr) { val = PyUnicode_AsUTF8(pystr); } -# else /* PY_MAJOR_VERSION >= 3 */ +#else /* PY_MAJOR_VERSION >= 3 */ if (pytype) { if (PyString_Check(pytype)) type = PyString_AsString(pytype); @@ -75,7 +92,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag if (pystr) { val = PyString_AsString(pystr); } -# endif /*PY_MAJOR_VERSION >= 3*/ +#endif /*PY_MAJOR_VERSION >= 3*/ } PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ @@ -115,39 +132,80 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag #endif /* HAVE_PYTHON */ } - +#ifdef HAVE_PYTHON +#if PY_MAJOR_VERSION >= 3 +void *pcilib_py_run_side_thread(void *arg) { + pcilib_t *ctx = (pcilib_t*)(arg); + //Initializing python + Py_Initialize(); + PyEval_InitThreads(); + PyEval_ReleaseLock(); + + //send initialization finish signal + pthread_cond_signal(&(ctx->py->thr_ctl->cond_finished)); + pthread_mutex_unlock(&(ctx->py->thr_ctl->cond_finished_lock)); + pthread_mutex_destroy(&(ctx->py->thr_ctl->cond_finished_lock)); + + //wait untill finish signal + pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock)); + pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished), + &(ctx->py->thr_ctl->cond_finished_lock)); + return NULL; +} +#endif /* PY_MAJOR_VERSION < 3 */ +#endif /* HAVE_PYTHON */ int pcilib_init_py(pcilib_t *ctx) { #ifdef HAVE_PYTHON ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; - memset(ctx->py, 0, sizeof(pcilib_py_t)); if(!Py_IsInitialized()) { - Py_Initialize(); - - // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads - PyEval_InitThreads(); - PyEval_ReleaseLock(); - ctx->py->finalyze = 1; - } - +#if PY_MAJOR_VERSION >= 3 + //create thread controller + ctx->py->thr_ctl = malloc(sizeof(pcilib_py_s_thread_control)); + if(!ctx->py->thr_ctl) return PCILIB_ERROR_MEMORY; + memset(ctx->py->thr_ctl, 0, sizeof(pcilib_py_s_thread_control)); + + //create side thread with python main loop + pthread_create(&(ctx->py->thr_ctl->pth), NULL, pcilib_py_run_side_thread, ctx); + pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock)); + + //wait until Python initializes + pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished), + &(ctx->py->thr_ctl->cond_finished_lock)); + +#else /* PY_MAJOR_VERSION < 3 */ + Py_Initialize(); + // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads + PyEval_InitThreads(); + PyEval_ReleaseLock(); +#endif /* PY_MAJOR_VERSION < 3 */ + ctx->py->finalyze = 1; + } + + + PyGILState_STATE gstate = PyGILState_Ensure(); + ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) { pcilib_python_warning("Error importing python parser"); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) { pcilib_python_warning("Error locating global python dictionary"); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER); if (!pywrap) { pcilib_python_warning("Error importing pcilib python wrapper"); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } @@ -159,8 +217,11 @@ int pcilib_init_py(pcilib_t *ctx) { if (!ctx->py->pcilib_pywrap) { pcilib_python_warning("Error initializing python wrapper"); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } + + PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ return 0; @@ -187,20 +248,24 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { if (!script_dir) return PCILIB_ERROR_MEMORY; sprintf(script_dir, "%s/%s", model_dir, dir); } + + PyGILState_STATE gstate = PyGILState_Ensure(); pypath = PySys_GetObject("path"); if (!pypath) { pcilib_python_warning("Can't get python path"); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } pynewdir = PyUnicode_FromString(script_dir); if (!pynewdir) { pcilib_python_warning("Can't create python string"); + PyGILState_Release(gstate); return PCILIB_ERROR_MEMORY; } - // Checking if the directory already in the path? + // Checking if the directory already in the path? pydict = PyDict_New(); if (pydict) { pystr = PyUnicode_FromString("cur"); @@ -227,8 +292,11 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { if (err) { pcilib_python_warning("Can't add directory (%s) to python path", script_dir); + PyGILState_Release(gstate); return err; } + + PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ return 0; @@ -237,7 +305,12 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { void pcilib_free_py(pcilib_t *ctx) { #ifdef HAVE_PYTHON int finalyze = 0; - + PyGILState_STATE gstate; + +#if PY_MAJOR_VERSION >= 3 + pcilib_py_s_thread_control *thr_ctl = ctx->py->thr_ctl; +#endif /* PY_MAJOR_VERSION < 3 */ + if (ctx->py) { if (ctx->py->finalyze) finalyze = 1; @@ -252,15 +325,44 @@ void pcilib_free_py(pcilib_t *ctx) { ctx->py->script_hash = NULL; } - if (ctx->py->pcilib_pywrap) + if (ctx->py->pcilib_pywrap) { + gstate = PyGILState_Ensure(); Py_DECREF(ctx->py->pcilib_pywrap); + PyGILState_Release(gstate); + } + free(ctx->py); ctx->py = NULL; } - if (finalyze) - Py_Finalize(); + + if (finalyze) { +#if PY_MAJOR_VERSION >= 3 + + //stop python side thread + pthread_cond_signal(&(thr_ctl->cond_finished)); + pthread_mutex_unlock(&(thr_ctl->cond_finished_lock)); + pthread_join(thr_ctl->pth, NULL); + + //free python + //must be finalized in main thread to correctly stop python threading + PyGILState_Ensure(); + Py_Finalize(); + + //destroy thread controllers + pthread_mutex_destroy(&(thr_ctl->cond_finished_lock)); + pthread_cond_destroy(&(thr_ctl->cond_finished)); + free(thr_ctl); + +#else /* PY_MAJOR_VERSION < 3 */ + + Py_Finalize(); + +#endif /* PY_MAJOR_VERSION < 3 */ + } + + #endif /* HAVE_PYTHON */ } @@ -268,6 +370,7 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { #ifdef HAVE_PYTHON PyObject* pymodule; pcilib_script_t *module = NULL; + PyGILState_STATE gstate; if (!ctx->py) return 0; @@ -284,11 +387,16 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { HASH_FIND_STR(ctx->py->script_hash, script_name, module); if (module) return 0; + gstate = PyGILState_Ensure(); + pymodule = PyImport_ImportModule(module_name); if (!pymodule) { pcilib_python_error("Error importing script (%s)", script_name); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } + + PyGILState_Release(gstate); module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); if (!module) return PCILIB_ERROR_MEMORY; @@ -307,6 +415,7 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ PyObject *dict; PyObject *pystr; pcilib_script_t *module; + PyGILState_STATE gstate; if (!ctx->py) { if (mode_ret) *mode_ret = mode; @@ -319,10 +428,13 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ pcilib_error("Script (%s) is not loaded yet", script_name); return PCILIB_ERROR_NOTFOUND; } + + gstate = PyGILState_Ensure(); dict = PyModule_GetDict(module->module); if (!dict) { pcilib_python_error("Error getting dictionary for script (%s)", script_name); + PyGILState_Release(gstate); return PCILIB_ERROR_FAILED; } @@ -337,6 +449,8 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; Py_DECREF(pystr); } + + PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ if (mode_ret) *mode_ret = mode; -- cgit v1.2.3 From 327b71b05b60a03e56fad618b51fbccd06c3776d Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 4 Mar 2016 12:33:44 +0100 Subject: Add python servers instalation step. Add systemd config files generation for python servers. --- pcilib/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index 27543e4..b24c7b3 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -21,6 +21,10 @@ install(FILES pcilib.h DESTINATION include ) -install(FILES bar.h kmem.h locking.h lock.h bank.h register.h xml.h dma.h event.h model.h error.h debug.h env.h tools.h timing.h cpu.h datacpy.h pagecpy.h memcpy.h export.h version.h view.h unit.h +install(FILES bar.h kmem.h locking.h lock.h bank.h register.h xml.h dma.h event.h model.h error.h debug.h env.h tools.h timing.h cpu.h datacpy.h pagecpy.h memcpy.h export.h view.h unit.h + DESTINATION include/pcilib +) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version.h DESTINATION include/pcilib ) -- cgit v1.2.3