tclspice for Windows

This commit is contained in:
h_vogt 2008-12-31 14:42:49 +00:00
parent 6ba6c6f17f
commit 1fa4faf88c
9 changed files with 138 additions and 18 deletions

View File

@ -1,3 +1,13 @@
2008-12-31 Holger Vogt
* resource.c: streamline resource info under Windows
* tclspice integration under Windows: dctran.c, inpfindl.c, outitf.c, alloc.c,
tclspice.c, winmain.c: type definitions, printf -> fprintf,
new heap for plot data to prevent memory fragmentation
* configure.in: new flags for TCL under Windows: HAS_TCLWIN
(is set instead of HAS_WINDOWS), TCLWIN (for generating makefiles,
instead of WINDOWS)
* cmath/makefile.am: prevent making test executables under TCL/Windows
2008-12-26 Dietmar Warning 2008-12-26 Dietmar Warning
* autogen.sh, configure.in: A hopeful way to integrate adms - ugly, but tested * autogen.sh, configure.in: A hopeful way to integrate adms - ugly, but tested
under linux, sunOS and msys with and w/o adms enabled. under linux, sunOS and msys with and w/o adms enabled.

View File

@ -274,9 +274,18 @@ dnl
dnl The tclSpice options dnl The tclSpice options
dnl dnl
AM_CONDITIONAL(TCL_MODULE, false) AM_CONDITIONAL(TCL_MODULE, false)
AM_CONDITIONAL(TCLWIN, false)
if test "x$with_tcl" != "x" -a "$with_tcl" != "no" ; then if test "x$with_tcl" != "x" -a "$with_tcl" != "no" ; then
AM_CONDITIONAL(TCL_MODULE, true) AM_CONDITIONAL(TCL_MODULE, true)
AC_DEFINE(TCL_MODULE,1,[Tcl Module]) AC_DEFINE(TCL_MODULE,1,[Tcl Module])
case $host_os in
*mingw* )
AM_CONDITIONAL(TCLWIN, true)
AC_DEFINE(HAS_TCLWIN,1,[Tcl Windows]);;
*)
;;
esac
with_x=no with_x=no
enable_shared=no enable_shared=no

View File

@ -64,6 +64,13 @@ static void freeRun(runDesc *run);
#endif #endif
/*saj*/ /*saj*/
/* plot output data shall go into extra heap
to prevent massive memory fragmentation of standard process heap */
#if defined(_MSC_VER) || defined(__MINGW32__)
#define newrealloc hrealloc
#else
#define newrealloc trealloc
#endif
#define DOUBLE_PRECISION 15 #define DOUBLE_PRECISION 15
@ -973,12 +980,12 @@ plotAddRealValue(dataDesc *desc, double value)
struct dvec *v = desc->vec; struct dvec *v = desc->vec;
if (isreal(v)) { if (isreal(v)) {
v->v_realdata = (double *) trealloc((char *) v->v_realdata, v->v_realdata = (double *) newrealloc((char *) v->v_realdata,
sizeof (double) * (v->v_length + 1)); sizeof (double) * (v->v_length + 1));
v->v_realdata[v->v_length] = value; v->v_realdata[v->v_length] = value;
} else { } else {
/* a real parading as a VF_COMPLEX */ /* a real parading as a VF_COMPLEX */
v->v_compdata = (complex *) trealloc((char *) v->v_compdata, v->v_compdata = (complex *) newrealloc((char *) v->v_compdata,
sizeof (complex) * (v->v_length + 1)); sizeof (complex) * (v->v_length + 1));
v->v_compdata[v->v_length].cx_real = value; v->v_compdata[v->v_length].cx_real = value;
v->v_compdata[v->v_length].cx_imag = (double) 0; v->v_compdata[v->v_length].cx_imag = (double) 0;
@ -994,7 +1001,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
{ {
struct dvec *v = desc->vec; struct dvec *v = desc->vec;
v->v_compdata = (complex *) trealloc((char *) v->v_compdata, v->v_compdata = (complex *) newrealloc((char *) v->v_compdata,
sizeof (complex) * (v->v_length + 1)); sizeof (complex) * (v->v_length + 1));
v->v_compdata[v->v_length].cx_real = value.real; v->v_compdata[v->v_length].cx_real = value.real;
v->v_compdata[v->v_length].cx_imag = value.imag; v->v_compdata[v->v_length].cx_imag = value.imag;

View File

@ -14,7 +14,8 @@ libcmaths_la_SOURCES = \
cmath4.h cmath4.h
## Test programs fail to build on Windows ## Test programs fail to build on Windows
if !WINDOWS if !WINDOWS
if !TCLWIN
noinst_PROGRAMS = test_cx_mag test_cx_j test_cx_ph noinst_PROGRAMS = test_cx_mag test_cx_j test_cx_ph
@ -44,6 +45,7 @@ test_cx_j_LDADD = \
TESTS = test_cx_mag test_cx_j test_cx_ph TESTS = test_cx_mag test_cx_j test_cx_ph
endif !TCLWIN
endif !WINDOWS endif !WINDOWS

View File

@ -19,6 +19,13 @@ $Id$
//#include <tclDecls.h> //#include <tclDecls.h>
#endif #endif
#if defined(_MSC_VER) || defined(__MINGW32__)
#undef BOOLEAN
#include <windows.h>
extern HANDLE outheap;
#endif
/* Malloc num bytes and initialize to zero. Fatal error if the space can't /* Malloc num bytes and initialize to zero. Fatal error if the space can't
* be tmalloc'd. Return NULL for a request for 0 bytes. * be tmalloc'd. Return NULL for a request for 0 bytes.
*/ */
@ -81,12 +88,53 @@ trealloc(void *ptr, size_t num)
#endif #endif
} }
if (!s) { if (!s) {
fprintf(stderr,"realloc: Internal Error: can't allocate %ld bytes.\n",(long)num); fprintf(stderr,"realloc: Internal Error: can't allocate %ld bytes.\n", (long)num);
exit(EXIT_BAD); exit(EXIT_BAD);
} }
return(s); return(s);
} }
/* realloc using the output heap.
Function is used in outitf.c to prevent heap fragmentation
An additional heap outheap is used to store the plot output data.
*/
#if defined(_MSC_VER) || defined(__MINGW32__)
void *
hrealloc(void *ptr, size_t num)
{
void *s;
/*saj*/
#ifdef TCL_MODULE
Tcl_Mutex *alloc;
alloc = Tcl_GetAllocMutex();
#endif
if (!num) {
if (ptr)
free(ptr);
return NULL;
}
if (!ptr)
s = HeapAlloc(outheap, HEAP_ZERO_MEMORY, num);
else {
/*saj*/
#ifdef TCL_MODULE
Tcl_MutexLock(alloc);
#endif
s = HeapReAlloc(outheap, HEAP_ZERO_MEMORY, ptr, num);
/*saj*/
#ifdef TCL_MODULE
Tcl_MutexUnlock(alloc);
#endif
}
if (!s) {
fprintf(stderr,"HeapReAlloc: Internal Error: can't allocate %ld bytes.\n", (long)num);
exit(EXIT_BAD);
}
return(s);
}
#endif
/* Original Berkeley Implementation */ /* Original Berkeley Implementation */

View File

@ -324,9 +324,16 @@ DCtran(CKTcircuit *ckt,
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
firsttime=0; firsttime=0;
/* To get rawfile working saj*/ /* To get rawfile working saj*/
/* get namelist again */
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
/* get timeUiD again */
(*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL,
"time", UID_OTHER, (void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList, ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList,
666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */ 666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */
tfree(nameList);
if(error) { if(error) {
fprintf(stderr, "Couldn't relink rawfile\n"); fprintf(stderr, "Couldn't relink rawfile\n");
return error; return error;

View File

@ -39,16 +39,16 @@ char *INPfindLev(char *line, int *level)
sscanf(where, "%2d", level); /* We get the level number */ sscanf(where, "%2d", level); /* We get the level number */
if (*level < 0) { if (*level < 0) {
*level = 1; *level = 1;
printf("Illegal value for level.\n"); fprintf(stderr,"Illegal value for level.\n");
printf("Level must be >0 (Setting level to 1)\n"); fprintf(stderr,"Level must be >0 (Setting level to 1)\n");
return (INPmkTemp return (INPmkTemp
(" illegal (negative) argument to level parameter - level=1 assumed")); (" illegal (negative) argument to level parameter - level=1 assumed"));
} }
if (*level > 99) { /* Limit to change in the future */ if (*level > 99) { /* Limit to change in the future */
*level = 1; *level = 1;
printf("Illegal value for level.\n"); fprintf(stderr,"Illegal value for level.\n");
printf("Level must be <99 (Setting Level to 1)\n"); fprintf(stderr,"Level must be <99 (Setting Level to 1)\n");
return (INPmkTemp return (INPmkTemp
(" illegal (too high) argument to level parameter - level=1 assumed")); (" illegal (too high) argument to level parameter - level=1 assumed"));
} }
@ -60,7 +60,7 @@ char *INPfindLev(char *line, int *level)
else { /* no level on the line => default */ else { /* no level on the line => default */
*level = 1; *level = 1;
printf("Warning -- Level not specified on line \"%s\"\nUsing level 1.\n", line); fprintf(stderr,"Warning -- Level not specified on line \"%s\"\nUsing level 1.\n", line);
return ((char *) NULL); return ((char *) NULL);
} }

View File

@ -177,6 +177,13 @@ do {\
spice_interp = interp;\ spice_interp = interp;\
} while(0) } while(0)
/* global handle for the output heap */
#if defined(_MSC_VER) || defined(__MINGW32__)
HANDLE outheap;
#endif
/****************************************************************************/ /****************************************************************************/
/* BLT and data routines */ /* BLT and data routines */
/****************************************************************************/ /****************************************************************************/
@ -601,26 +608,33 @@ static threadId_t tid, bgtid=(threadId_t)0;
static bool fl_running = FALSE; static bool fl_running = FALSE;
static bool fl_exited = TRUE; static bool fl_exited = TRUE;
#if defined(__MINGW32__) || defined(_MSC_VER)
static void *_thread_run(void *string){ static void * WINAPI _thread_run(void *string){
#else
static void * _thread_run(void *string){
#endif
fl_exited = FALSE; fl_exited = FALSE;
bgtid = thread_self(); bgtid = thread_self();
cp_evloop((char *)string); cp_evloop((char *)string);
FREE(string); FREE(string);
bgtid = (threadId_t)0; bgtid = (threadId_t)0;
fl_exited = TRUE; fl_exited = TRUE;
return 0; return;
} }
/*Stops a running thread, hopefully */ /*Stops a running thread, hopefully */
#if defined(__MINGW32__) || defined(_MSC_VER)
static int WINAPI _thread_stop(){
#else
static int _thread_stop(){ static int _thread_stop(){
#endif
int timeout = 0; int timeout = 0;
if(fl_running) { if(fl_running) {
while(!fl_exited && timeout < 100){ while(!fl_exited && timeout < 100){
ft_intrpt = TRUE; ft_intrpt = TRUE;
timeout++; timeout++;
#if defined(__MINGW32__) || defined(_MSC_VER) #if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(10); /* va: windows native */ Sleep(100); /* va: windows native */
#else #else
usleep(10000); usleep(10000);
#endif #endif
@ -663,12 +677,17 @@ static int _run(int argc,char **argv){
} }
#endif #endif
/* Catch Ctrl-C to break simulations */ /* Catch Ctrl-C to break simulations */
#ifndef _MSC_VER_
oldHandler = signal(SIGINT,ft_sigintr); oldHandler = signal(SIGINT,ft_sigintr);
if(SETJMP(jbuf, 1)!=0) { if(SETJMP(jbuf, 1)!=0) {
signal(SIGINT,oldHandler); signal(SIGINT,oldHandler);
return TCL_OK; return TCL_OK;
} }
#else
oldHandler = SIG_IGN;
#endif
/*build a char * to pass to cp_evloop */ /*build a char * to pass to cp_evloop */
for(i=0;i<argc;i++) { for(i=0;i<argc;i++) {
@ -1665,6 +1684,7 @@ void triggerEventCheck(ClientData clientData,int flags) {
#endif #endif
} }
int Tcl_ExecutePerLoop() { int Tcl_ExecutePerLoop() {
struct watch *current; struct watch *current;
@ -2135,6 +2155,16 @@ int Spice_Init(Tcl_Interp *interp) {
save_interp(); save_interp();
#if defined(_MSC_VER) || defined(__MINGW32__)
/* create private heap for current process*/
outheap = HeapCreate(0, 10000000, 0);
if (!outheap) {
fprintf(stderr,"HeapCreate: Internal Error: can't allocate private output heap");
exit(EXIT_BAD);
}
#endif
{ {
extern void DevInit(); extern void DevInit();
int i; int i;

View File

@ -97,6 +97,9 @@ void DisplayText( void);
char* rlead(char*); char* rlead(char*);
void winmessage(char*); void winmessage(char*);
/* private heap for storing plot data */
HANDLE outheap;
// --------------------------<History-Verwaltung>------------------------------ // --------------------------<History-Verwaltung>------------------------------
// Alle Puffer loeschen und Zeiger auf den Anfang setzen // Alle Puffer loeschen und Zeiger auf den Anfang setzen
@ -844,10 +847,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
UpdateWindow( hwMain); UpdateWindow( hwMain);
SetFocus( swString); SetFocus( swString);
status = MakeArgcArgv(lpszCmdLine,&argc,&argv); status = MakeArgcArgv(lpszCmdLine,&argc,&argv);
/* create private heap for current process */
outheap = HeapCreate(0, 10000000, 0);
if (!outheap) {
fprintf(stderr,"HeapCreate: Internal Error: can't allocate private output heap");
exit(1);
}
// Warten, bis alles klar ist // Wait util everything is settled
WaitForIdle(); WaitForIdle();
// Ab nach main() // Ab nach main()
@ -855,8 +864,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
THE_END: THE_END:
// 3D abschalten
// Ctl3dUnregister( hInstance);
// terminate // terminate
return nReturnCode; return nReturnCode;