Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

289 lines
7.8 KiB

/*
* Copyright(C) 1999-2020 National Technology & Engineering Solutions
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
* NTESS, the U.S. Government retains certain rights in this software.
*
* See packages/seacas/LICENSE for details
*/
#include <stddef.h> // for size_t
#include <stdio.h> // for NULL, fprintf, printf, FILE, etc
#include <stdlib.h> // for malloc, free, realloc
static int nmalloc = 0; /* number of calls to malloc */
static int nfree = 0; /* number of calls to free */
static size_t bytes_used = 0; /* current dynamic memory usage */
static size_t bytes_max = 0; /* largest dynamic memory usage */
static struct smalloc_debug_data
{
int order; /* which smalloc call is it? */
size_t size; /* size of malloc invocation */
double * ptr; /* memory location returned */
struct smalloc_debug_data *next; /* pointer to next element */
} *top = NULL;
void message(char *msg, size_t n, FILE *ofile)
{
fprintf(stderr, msg, n);
if (ofile != NULL) {
fprintf(ofile, msg, n);
}
}
void sfree(void *ptr);
/* Safe version of malloc. Does not initialize memory .*/
void *smalloc(size_t n)
{
extern FILE *Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
void * ptr; /* return value */
struct smalloc_debug_data *new; /* data structure for malloc data */
void bail(char *msg, int status);
nmalloc++;
if (n == 0) {
message("ERROR: Non-positive argument to smalloc (%zu).\n", n, Output_File);
bail(NULL, 1);
}
ptr = malloc(n);
if (ptr == NULL) {
message("Program out of space while attempting to allocate %zu.\n", n, Output_File);
bail(NULL, 1);
}
if (DEBUG_MEMORY > 1) {
new = (struct smalloc_debug_data *)malloc(sizeof(struct smalloc_debug_data));
if (new == NULL) {
message("WARNING: No space for malloc_debug %zu.\n", n, Output_File);
return (ptr);
}
new->order = nmalloc;
new->size = n;
new->ptr = ptr;
new->next = top;
top = new;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
if (DEBUG_MEMORY > 2) {
printf(" order=%d, size=%zu, location=%p\n", nmalloc, n, ptr);
}
return (ptr);
}
/* Safe version of malloc. Does not initialize memory .*/
/* Returns instead of dying if it fails. */
void *smalloc_ret(size_t n)
{
extern FILE *Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
void * ptr; /* return value */
struct smalloc_debug_data *new; /* data structure for malloc data */
void bail(char *msg, int status);
ptr = NULL;
if (n == 0) {
message("ERROR: Non-positive argument to smalloc_ret (%zu).\n", n, Output_File);
bail(NULL, 1);
}
else {
nmalloc++;
ptr = malloc(n);
if (ptr == NULL) {
nmalloc--;
message("\nERROR: Unable to allocate %zu bytes of memory.\n", n, Output_File);
}
else {
if (DEBUG_MEMORY > 1) {
new = (struct smalloc_debug_data *)malloc(sizeof(struct smalloc_debug_data));
if (new == NULL) {
message("WARNING: No space for malloc_debug %zu.\n", n, Output_File);
return (ptr);
}
new->order = nmalloc;
new->size = n;
new->ptr = ptr;
new->next = top;
top = new;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
if (DEBUG_MEMORY > 2) {
printf(" order=%d, size=%zu, location=%p\n", nmalloc, n, ptr);
}
}
}
return (ptr);
}
/* Safe version of realloc */
void *srealloc(void *ptr, size_t n)
{
extern FILE * Output_File; /* output file or null */
void * p; /* returned pointer */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
void bail(char *msg, int status);
if (ptr == NULL) {
if (n == 0) {
return (NULL);
}
p = smalloc(n);
}
else {
if (n == 0) {
sfree(ptr);
return (NULL);
}
p = realloc(ptr, n);
if (DEBUG_MEMORY > 1) {
for (dbptr = top; dbptr != NULL && dbptr->ptr != ptr; dbptr = dbptr->next) {
;
}
if (dbptr == NULL) {
fprintf(stderr, "Memory error: In srealloc, address not found in debug list (%p)\n", ptr);
}
else {
dbptr->size = n;
dbptr->ptr = p;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
}
}
if (p == NULL) {
message("Program out of space while attempting to reallocate %zu.\n", n, Output_File);
bail(NULL, 1);
}
return (p);
}
/* Safe version of realloc */
/* Returns instead of dying if it fails. */
void *srealloc_ret(void *ptr, size_t n)
{
extern FILE * Output_File; /* output file or null */
void * p; /* returned pointer */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
if (ptr == NULL) {
if (n == 0) {
return (NULL);
}
p = smalloc(n);
}
else {
if (n == 0) {
sfree(ptr);
return (NULL);
}
p = realloc(ptr, n);
if (DEBUG_MEMORY > 1) {
for (dbptr = top; dbptr != NULL && dbptr->ptr != ptr; dbptr = dbptr->next) {
;
}
if (dbptr == NULL) {
fprintf(stderr, "Memory error: In srealloc_ret, address not found in debug list (%p)\n",
ptr);
}
else {
dbptr->size = n;
dbptr->ptr = p;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
}
}
if (p == NULL && DEBUG_MEMORY > 0) {
message("WARNING: Program out of space while attempting to reallocate %zu.\n", n, Output_File);
}
return (p);
}
/* Safe version of free. */
void sfree(void *ptr)
{
extern FILE * Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data * dbptr; /* loops through debug list */
struct smalloc_debug_data **prev; /* holds previous pointer */
if (DEBUG_MEMORY > 1) {
if (ptr != NULL) { /* search through debug list for it */
prev = &top;
for (dbptr = top; dbptr != NULL && dbptr->ptr != ptr; dbptr = dbptr->next) {
prev = &(dbptr->next);
}
if (dbptr == NULL) {
fprintf(stderr, "Memory error: In sfree, address not found in debug list (%p)\n", ptr);
if (Output_File != NULL) {
fprintf(Output_File, "Memory error: In sfree, address not found in debug list (%p)\n",
ptr);
}
}
else {
*prev = dbptr->next;
bytes_used -= dbptr->size;
free(dbptr);
}
}
}
if (ptr != NULL) {
nfree++;
free(ptr);
}
}
void smalloc_stats(void)
{
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
if (DEBUG_MEMORY == 1) {
printf("Calls to smalloc = %d, Calls to sfree = %d\n", nmalloc, nfree);
}
if (DEBUG_MEMORY > 1) {
printf("Calls to smalloc = %d, Calls to sfree = %d, maximum bytes = %zu\n", nmalloc, nfree,
bytes_max);
if (top != NULL) {
printf("Remaining allocations:\n");
for (dbptr = top; dbptr != NULL; dbptr = dbptr->next) {
printf(" order=%d, size=%zu, location=%p\n", dbptr->order, dbptr->size, (void *)dbptr->ptr);
}
}
}
}
int smalloc_num(void) { return (nmalloc); }