shared ngspice: add a third thread to execute the .control commands

only after the background thread has been finished
This commit is contained in:
Holger Vogt 2018-12-08 20:02:57 +01:00
parent 7706889a0a
commit e4aabc82c7
2 changed files with 56 additions and 2 deletions

View File

@ -71,6 +71,10 @@ void eval_seed_opt(struct card *deck);
extern bool ft_batchmode;
#ifdef SHARED_MODULE
extern void exec_controls(wordlist *controls);
#endif
/* structure used to save expression parse trees for .model and
* device instance lines
*/
@ -937,9 +941,18 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
/* Now that the deck is loaded, do the commands, if there are any */
controls = wl_reverse(controls);
/* in shared ngspice controls a execute in the primary thread, typically
before the background thread has finished. This leads to premature execution
of commands. Thus this is delegated to a function using a third thread, that
only start when the background threas has finished (sharedspice.c).*/
#ifdef SHARED_MODULE
exec_controls(controls);
#else
for (wl = controls; wl; wl = wl->wl_next)
cp_evloop(wl->wl_word);
wl_free(controls);
#endif
}
/* Now reset everything. Pop the control stack, and fix up the IO

View File

@ -178,7 +178,7 @@ extern int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator);
extern wordlist *cp_varwl(struct variable *var);
extern void create_circbyline(char *line);
void exec_controls(wordlist *controls);
/*The current run (to get variable names, etc)*/
static runDesc *cur_run;
@ -290,7 +290,7 @@ get_plot_byname(char* plotname)
#ifdef __MINGW32__
static threadId_t tid, printtid; // , bgtid;
#else
static threadId_t tid, printtid; // , bgtid = (threadId_t) 0;
static threadId_t tid, printtid, tid2; // , bgtid = (threadId_t) 0;
#endif
static bool fl_running = FALSE;
@ -305,6 +305,17 @@ static bool ps_exited = TRUE;
#define EXPORT_FLAVOR
#endif
/* starts a thread to run the controls, started when bg thread finishes */
static void * EXPORT_FLAVOR
_cthread_run(void *controls)
{
wordlist *wl;
for (wl = controls; wl; wl = wl->wl_next)
cp_evloop(wl->wl_word);
wl_free(controls);
return NULL;
}
/* starts a background thread, e.g. from command bg_run */
static void * EXPORT_FLAVOR
_thread_run(void *string)
@ -327,6 +338,14 @@ _thread_run(void *string)
/* notify caller that thread has exited */
if (!nobgtrwanted)
bgtr(fl_exited, ng_ident, userptr);
#ifdef HAVE_LIBPTHREAD
#elif defined _MSC_VER || defined __MINGW32__
ResumeThread(tid2);
#else
#endif
return NULL;
}
@ -381,6 +400,28 @@ sighandler_sharedspice(int num)
#endif /*THREADS*/
void
exec_controls(wordlist *controls)
{
#ifdef THREADS
#ifdef HAVE_LIBPTHREAD
usleep(20000); /* wait a little */
pthread_join(tid, NULL); /* wait wait for background thread to return */
pthread_create(&tid2, NULL, (void * (*)(void *))_cthread_run, (void *)controls);
#elif defined _MSC_VER || defined __MINGW32__
tid2 = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(__stdcall *)(void *))_cthread_run,
(void*)controls, CREATE_SUSPENDED, NULL);
#else
tid2 = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)_cthread_run, (void*)controls,
0, NULL);
#endif
#else
wordlist *wl;
for (wl = controls; wl; wl = wl->wl_next)
cp_evloop(wl->wl_word);
#endif
}
/* run a ngspice command */
static int