245 lines
5.0 KiB
C

/* This file is part of the Project Athena Zephyr Notification System.
* It is one of the source files comprising zwgc, the Zephyr WindowGram
* client.
*
* Created by: Marc Horowitz <marc@athena.mit.edu>
*
* $Id$
*
* Copyright (c) 1989 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
* "mit-copyright.h".
*/
#include <sysdep.h>
#if (!defined(lint) && !defined(SABER))
static const char rcsid_new_memory_c[] = "$Id$";
#endif
#if !defined(SABER) && (defined(DEBUG) || defined(MEMORY_DEBUG))
/*
* memory - module wrapping debugging code around normal malloc/free/etc.
* routines.
*
* Overview:
*
* ...
*/
#define memory__PROVIDER
#include "new_memory.h"
/*
*
*/
#ifdef DEBUG
#define assert(x) if (!(x)) abort()
#else
#define assert(x)
#endif
/*
*
*/
#ifdef DEBUG_MEMORY
extern void record_request();
char *current_module = 0;
int current_line = -1;
#endif
/*
* string string_CreateFromData(char *data, int length):
* Requires: data[0], data[1], ..., data[length-1] != 0
* Effects: Takes the first length characters at data and
* creates a string containing them. The returned string
* is on the heap & must be freed eventually.
* I.e., if passed "foobar" and 3, it would return
* string_Copy("foo").
*/
void *memory__malloc(size)
unsigned size;
{
char *result;
result = malloc(size + memory__size_of_header);
if (!result)
abort(); /* <<<>>> */
#ifdef DEBUG_MEMORY
((memory_block_header *)result)->size = size;
((memory_block_header *)result)->creating_module = current_module;
((memory_block_header *)result)->line_number_in_creating_module =
current_line;
((memory_block_header *)result)->check_field = CHECK_FIELD_VALUE;
result += memory__size_of_header;
record_request(current_module, current_line, 1, size);
#endif
return(result);
}
void *memory__realloc(aptr, size)
void *aptr;
unsigned size;
{
char *result, *ptr = aptr;
assert(ptr);
#ifdef DEBUG_MEMORY
if (!memory__on_heap_p(ptr)) {
printf("realloced non-memory block in %s on line %d!\n",
current_module, current_line);
fflush(stdout);
return(realloc(ptr, size));
}
#endif
result = realloc(ptr-memory__size_of_header, size+memory__size_of_header);
if (!result)
abort(); /* <<<>>> */
return(result+memory__size_of_header);
}
void *memory__calloc(nelem, elsize)
unsigned nelem;
unsigned elsize;
{
char *result;
#ifdef DEBUG_MEMORY
printf("in calloc\n"); fflush(stdout);
#endif
abort();
#ifdef FRED
result = calloc(nelem, elsize);
if (!result)
abort();
record_request(1);
#endif
return(result);
}
void memory__free(aptr)
void *aptr;
{
char *ptr = aptr;
assert(ptr);
#ifdef DEBUG_MEMORY
if (!memory__on_heap_p(ptr)) {
printf("freed non-memory block in %s on line %d!\n", current_module,
current_line);
fflush(stdout);
(void)free(ptr);
return;
}
record_request(memory__get_header(ptr)->creating_module,
memory__get_header(ptr)->line_number_in_creating_module,
-1,
memory__get_header(ptr)->size);
#endif
(void)free(ptr-memory__size_of_header);
}
#ifdef DEBUG_MEMORY
#include "int_dictionary.h"
static int request_off = 0;
static int_dictionary requests = 0;
static int outstanding_requests = 0;
static int outstanding_memory = 0;
void record_request(module, line_number, dir, size)
char *module;
int line_number;
int dir;
unsigned int size;
{
int_dictionary_binding *binding;
int already_exists;
#ifdef LINE
char buffer[20];
#endif
if (request_off)
return;
request_off = 1;
if (!requests)
requests = int_dictionary_Create(101);
#ifdef LINE
module = string_Concat(module, ":");
sprintf(buffer, "%d", line_number);
module = string_Concat2(module, buffer);
#endif
binding = int_dictionary_Define(requests, module, &already_exists);
if (!already_exists)
binding->value = 0;
#ifdef LINE
free(module);
#endif
binding->value += dir;
outstanding_requests += dir;
outstanding_memory += size*dir;
request_off = 0;
}
void proc(binding)
int_dictionary_binding *binding;
{
if (binding->value)
printf(" %-30s %6d blocks allocated\n", binding->key, binding->value);
}
void report_memory_usage()
{
printf("\n# of blocks on the heap = %d\n", outstanding_requests);
printf("Total heap space in use: %d bytes\n", outstanding_memory);
printf("\nHeap Allocations by module:\n");
int_dictionary_Enumerate(requests, proc);
printf("\n");
fflush(stdout);
}
void set_module(file, line)
char *file;
int line;
{
if (request_off)
return;
if (!strcmp(file, "new_string.c"))
return;
if (!strcmp(file, "string_dictionary_aux.c"))
return;
current_line = line;
current_module = file;
}
#endif
#endif /* SABER */