From 0667b7ba637b62a79643a0c463cd21e02fc09269 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 11 Aug 2016 14:42:18 +0200 Subject: [PATCH] Fixed ngspice freeze when there is an error in the simulated netlist Does not work with current ngspice head, it has to be compiled from the official master branch. --- eeschema/sim/ngspice.cpp | 69 ++++++++++++++++++++++++++-------------- eeschema/sim/ngspice.h | 5 +++ 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp index 54a5c8ffc4..2961f5dc5e 100644 --- a/eeschema/sim/ngspice.cpp +++ b/eeschema/sim/ngspice.cpp @@ -35,23 +35,7 @@ using namespace std; NGSPICE::NGSPICE() { -#ifdef __WINDOWS__ - m_dll = new wxDynamicLibrary( "libngspice-0.dll" ); -#else - m_dll = new wxDynamicLibrary( wxDynamicLibrary::CanonicalizeName( "ngspice" ) ); -#endif - - if( !m_dll || !m_dll->IsLoaded() ) - throw std::runtime_error( "Missing ngspice shared library" ); - - // Obtain function pointers - m_ngSpice_Init = (ngSpice_Init) m_dll->GetSymbol( "ngSpice_Init" ); - m_ngSpice_Circ = (ngSpice_Circ) m_dll->GetSymbol( "ngSpice_Circ" ); - m_ngSpice_Command = (ngSpice_Command) m_dll->GetSymbol( "ngSpice_Command" ); - m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll->GetSymbol( "ngGet_Vec_Info" ); - m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll->GetSymbol( "ngSpice_AllPlots" ); - m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll->GetSymbol( "ngSpice_AllVecs" ); - m_ngSpice_Running = (ngSpice_Running) m_dll->GetSymbol( "ngSpice_running" ); + init_dll(); } @@ -63,9 +47,14 @@ NGSPICE::~NGSPICE() void NGSPICE::Init() { - setlocale( LC_ALL, "C" ); - m_ngSpice_Init( &cbSendChar, &cbSendStat, &cbControlledExit, NULL, NULL, &cbBGThreadRunning, this ); - setlocale( LC_ALL, "" ); + if( m_error ) + { + delete m_dll; + init_dll(); + } + + Command( "reset" ); + Command( "remcirc" ); } @@ -301,10 +290,33 @@ string NGSPICE::GetXAxis( SIM_TYPE aType ) const } -int NGSPICE::cbControlledExit( int status, bool immediate, bool exit_upon_quit, int id, void* user ) +void NGSPICE::init_dll() { - //printf("stat %d immed %d quit %d\n", status, !!immediate, !!exit_upon_quit); - return 0; +#ifdef __WINDOWS__ + m_dll = new wxDynamicLibrary( "libngspice-0.dll" ); +#else + m_dll = new wxDynamicLibrary( wxDynamicLibrary::CanonicalizeName( "ngspice" ) ); +#endif + + if( !m_dll || !m_dll->IsLoaded() ) + throw std::runtime_error( "Missing ngspice shared library" ); + + m_error = false; + + // Obtain function pointers + m_ngSpice_Init = (ngSpice_Init) m_dll->GetSymbol( "ngSpice_Init" ); + m_ngSpice_Circ = (ngSpice_Circ) m_dll->GetSymbol( "ngSpice_Circ" ); + m_ngSpice_Command = (ngSpice_Command) m_dll->GetSymbol( "ngSpice_Command" ); + m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll->GetSymbol( "ngGet_Vec_Info" ); + m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll->GetSymbol( "ngSpice_AllPlots" ); + m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll->GetSymbol( "ngSpice_AllVecs" ); + m_ngSpice_Running = (ngSpice_Running) m_dll->GetSymbol( "ngSpice_running" ); // it is not a typo + + setlocale( LC_ALL, "C" ); + m_ngSpice_Init( &cbSendChar, &cbSendStat, &cbControlledExit, NULL, NULL, &cbBGThreadRunning, this ); + // Workaround to avoid hang ups on certain errors + Command( "unset interactive" ); + setlocale( LC_ALL, "" ); } @@ -346,3 +358,14 @@ int NGSPICE::cbBGThreadRunning( bool is_running, int id, void* user ) return 0; } + + +int NGSPICE::cbControlledExit( int status, bool immediate, bool exit_upon_quit, int id, void* user ) +{ + // Something went wrong, reload the dll + NGSPICE* sim = reinterpret_cast( user ); + sim->m_error = true; + //printf("stat %d immed %d quit %d\n", status, !!immediate, !!exit_upon_quit); + + return 0; +} diff --git a/eeschema/sim/ngspice.h b/eeschema/sim/ngspice.h index 5fa3f9c7ce..b24aada872 100644 --- a/eeschema/sim/ngspice.h +++ b/eeschema/sim/ngspice.h @@ -73,6 +73,11 @@ public: std::vector GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) override; private: + bool m_error; + + // Performs DLL initialization, obtains function pointers + void init_dll(); + // ngspice library functions typedef void (*ngSpice_Init)( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*, BGThreadRunning*, void* );