2000-04-27 22:03:57 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
|
|
|
**********/
|
|
|
|
|
|
2013-03-24 12:54:11 +01:00
|
|
|
/* for thread handling */
|
|
|
|
|
#if defined __MINGW32__ || defined _MSC_VER
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
/*
|
|
|
|
|
* Memory alloction functions
|
|
|
|
|
*/
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/ngspice.h"
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2012-08-03 08:28:50 +02:00
|
|
|
|
2013-03-24 12:54:11 +01:00
|
|
|
#ifdef SHARED_MODULE
|
|
|
|
|
#ifndef HAVE_LIBPTHREAD
|
|
|
|
|
#ifdef SRW
|
|
|
|
|
#define mutex_lock(a) AcquireSRWLockExclusive(a)
|
|
|
|
|
#define mutex_unlock(a) ReleaseSRWLockExclusive(a)
|
|
|
|
|
typedef SRWLOCK mutexType;
|
|
|
|
|
#else
|
|
|
|
|
#define mutex_lock(a) EnterCriticalSection(a)
|
|
|
|
|
#define mutex_unlock(a) LeaveCriticalSection(a)
|
|
|
|
|
typedef CRITICAL_SECTION mutexType;
|
|
|
|
|
#endif
|
|
|
|
|
extern mutexType allocMutex;
|
|
|
|
|
#else
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#define mutex_lock(a) pthread_mutex_lock(a)
|
|
|
|
|
#define mutex_unlock(a) pthread_mutex_unlock(a)
|
|
|
|
|
typedef pthread_mutex_t mutexType;
|
|
|
|
|
extern mutexType allocMutex;
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
2000-10-14 23:49:25 +02:00
|
|
|
#ifndef HAVE_LIBGC
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj For Tcl module locking*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
#include <tcl.h>
|
|
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
/* Malloc num bytes and initialize to zero. Fatal error if the space can't
|
* src/main.c, src/multidec.c, src/proc2mod.c,
src/frontend/display.c, src/frontend/outitf.c,
src/frontend/help/readhelp.c, src/frontend/help/x11disp.c,
src/frontend/parser/complete.c, src/frontend/parser/glob.c,
src/frontend/plotting/graf.c,
src/frontend/plotting/graphdb.c,
src/frontend/plotting/x11.c, src/include/graph.h,
src/include/iferrmsg.h, src/include/ifsim.h,
src/include/macros.h, src/maths/poly/polyfit.c,
src/maths/sparse/spalloc.c, src/maths/sparse/spconfig.h,
src/misc/alloc.c, src/misc/mktemp.c,
src/spicelib/analysis/cktpzstr.c,
src/spicelib/devices/bsim2/b2temp.c,
src/spicelib/devices/bsim3/b3temp.c,
src/spicelib/devices/bsim3v1/b3v1temp.c,
src/spicelib/devices/bsim3v2/b3v2temp.c,
src/spicelib/devices/bsim4/b4temp.c: replaced malloc
realloc and free calls to use tmalloc trealloc and txfree.
* tests/diffpair.out, tests/fourbitadder.out,
tests/resistance/res_partition.out: Updated.
2000-10-14 15:16:53 +02:00
|
|
|
* be tmalloc'd. Return NULL for a request for 0 bytes.
|
2000-04-27 22:03:57 +02:00
|
|
|
*/
|
|
|
|
|
|
2016-07-22 20:44:17 +02:00
|
|
|
/* New implementation of tmalloc, it uses calloc and does not call memset() */
|
2000-04-27 22:03:57 +02:00
|
|
|
void *
|
|
|
|
|
tmalloc(size_t num)
|
|
|
|
|
{
|
|
|
|
|
void *s;
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_Mutex *alloc;
|
|
|
|
|
alloc = Tcl_GetAllocMutex();
|
|
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!num)
|
|
|
|
|
return NULL;
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_MutexLock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#elif defined SHARED_MODULE
|
|
|
|
|
mutex_lock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
s = calloc(num,1);
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_MutexUnlock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#elif defined SHARED_MODULE
|
|
|
|
|
mutex_unlock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!s){
|
2005-05-21 17:56:20 +02:00
|
|
|
fprintf(stderr,"malloc: Internal Error: can't allocate %ld bytes. \n",(long)num);
|
2013-03-24 12:54:11 +01:00
|
|
|
#if defined HAS_WINGUI || defined SHARED_MODULE
|
2012-08-03 08:28:50 +02:00
|
|
|
controlled_exit(EXIT_FAILURE);
|
|
|
|
|
#else
|
2012-08-01 22:10:13 +02:00
|
|
|
exit(EXIT_FAILURE);
|
2012-08-03 08:28:50 +02:00
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
return(s);
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-09 21:19:57 +01:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
void *
|
2016-06-16 20:01:49 +02:00
|
|
|
trealloc(const void *ptr, size_t num)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
|
|
|
|
void *s;
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_Mutex *alloc;
|
|
|
|
|
alloc = Tcl_GetAllocMutex();
|
|
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!num) {
|
|
|
|
|
if (ptr)
|
2016-06-16 20:01:49 +02:00
|
|
|
free((void*) ptr);
|
2000-04-27 22:03:57 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
|
s = tmalloc(num);
|
2008-08-27 15:39:05 +02:00
|
|
|
else {
|
|
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_MutexLock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#elif defined SHARED_MODULE
|
|
|
|
|
mutex_lock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
2016-06-16 20:01:49 +02:00
|
|
|
s = realloc((void*) ptr, num);
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_MutexUnlock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#elif defined SHARED_MODULE
|
|
|
|
|
mutex_unlock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!s) {
|
2008-12-31 15:42:49 +01:00
|
|
|
fprintf(stderr,"realloc: Internal Error: can't allocate %ld bytes.\n", (long)num);
|
2013-03-24 12:54:11 +01:00
|
|
|
#if defined HAS_WINGUI || defined SHARED_MODULE
|
2012-08-03 08:28:50 +02:00
|
|
|
controlled_exit(EXIT_FAILURE);
|
|
|
|
|
#else
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
#endif
|
2008-12-31 15:42:49 +01:00
|
|
|
}
|
|
|
|
|
return(s);
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
void
|
2016-06-16 20:01:49 +02:00
|
|
|
txfree(const void *ptr)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_Mutex *alloc;
|
|
|
|
|
alloc = Tcl_GetAllocMutex();
|
|
|
|
|
Tcl_MutexLock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#endif
|
|
|
|
|
#ifdef SHARED_MODULE
|
|
|
|
|
mutex_lock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
if (ptr)
|
2016-06-16 20:01:49 +02:00
|
|
|
free((void*) ptr);
|
2008-08-27 15:39:05 +02:00
|
|
|
/*saj*/
|
|
|
|
|
#ifdef TCL_MODULE
|
|
|
|
|
Tcl_MutexUnlock(alloc);
|
2013-03-24 12:54:11 +01:00
|
|
|
#elif defined SHARED_MODULE
|
|
|
|
|
mutex_unlock(&allocMutex);
|
2008-08-27 15:39:05 +02:00
|
|
|
#endif
|
2020-04-25 19:54:28 +02:00
|
|
|
} /* end of function txfree */
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2020-04-25 19:54:28 +02:00
|
|
|
|
|
|
|
|
/* This function returns the product of a and b if it does not overflow.
|
|
|
|
|
*
|
|
|
|
|
* Return codes
|
|
|
|
|
* 0: No overflow
|
|
|
|
|
* 1: overflow
|
|
|
|
|
*/
|
|
|
|
|
static inline int product_overflow(size_t a, size_t b, size_t *p_n)
|
|
|
|
|
{
|
|
|
|
|
/* Some overflow conditions:
|
|
|
|
|
* a == SIZE_MAX and b > 1
|
|
|
|
|
* a > 1 and b == SIZE_MAX
|
|
|
|
|
* a * b < a
|
|
|
|
|
* a * b < b
|
|
|
|
|
*/
|
|
|
|
|
if ((a == SIZE_MAX && b > 1) || (a > 1 && b == SIZE_MAX)) {
|
|
|
|
|
return +1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const size_t n = a * b;
|
|
|
|
|
if (n < a || n < b) {
|
|
|
|
|
return +1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*p_n = n;
|
|
|
|
|
return 0;
|
|
|
|
|
} /* end of function product_overflow */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Print error related to allocating a product that cannot fit in a
|
|
|
|
|
* size_t and exit. This function does not return. */
|
|
|
|
|
static void overflow_error(size_t num, size_t size)
|
|
|
|
|
{
|
|
|
|
|
(void) fprintf(stderr, "Cannot allocate %zu X %zu bytes: "
|
|
|
|
|
"Product exceeds largest size_t = %zu.\n",
|
|
|
|
|
num, size, SIZE_MAX);
|
2020-04-25 20:22:40 +02:00
|
|
|
#if defined HAS_WINGUI || defined SHARED_MODULE
|
2020-04-25 19:54:28 +02:00
|
|
|
controlled_exit(EXIT_FAILURE);
|
2020-04-25 20:22:40 +02:00
|
|
|
#else
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
#endif
|
2020-04-25 19:54:28 +02:00
|
|
|
} /* end of function overflow_error */
|
|
|
|
|
|
|
|
|
|
#endif /* #ifndef HAVE_LIBGC */
|