312 lines
6.2 KiB
C
312 lines
6.2 KiB
C
//metadoc Common copyright Steve Dekorte 2002
|
|
//metadoc Common license BSD revised
|
|
|
|
#include "Common.h"
|
|
#include <stdio.h>
|
|
|
|
#ifdef IO_CHECK_ALLOC
|
|
|
|
static long allocs = 0;
|
|
static long reallocs = 0;
|
|
static long allocatedBytes = 0;
|
|
static long maxAllocatedBytes = 0;
|
|
static long frees = 0;
|
|
|
|
/*
|
|
typedef struct
|
|
{
|
|
long allocs = 0;
|
|
long reallocs = 0;
|
|
long allocatedBytes = 0;
|
|
long maxAllocatedBytes = 0;
|
|
long frees = 0;
|
|
} Allocator;
|
|
|
|
Allocator *Allocator_new(void)
|
|
{
|
|
Allocator *self = calloc(1, sizeof(Allocator));
|
|
return self;
|
|
}
|
|
|
|
void Allocator_free(Allocator *self)
|
|
{
|
|
free(self);
|
|
}
|
|
|
|
size_t Allocator_allocs(Allocator *self)
|
|
{
|
|
return self->allocs;
|
|
}
|
|
|
|
size_t Allocator_frees(Allocator *self)
|
|
{
|
|
return self->frees;
|
|
}
|
|
|
|
size_t Allocator_allocatedBytes(Allocator *self)
|
|
{
|
|
return self->allocatedBytes;
|
|
}
|
|
|
|
size_t Allocator_maxAllocatedBytes(Allocator *self)
|
|
{
|
|
return self->maxAllocatedBytes;
|
|
}
|
|
|
|
void Allocator_resetMaxAllocatedBytes(Allocator *self)
|
|
{
|
|
self->maxAllocatedBytes = self->allocatedBytes;
|
|
}
|
|
|
|
void Allocator_show(Allocator *self)
|
|
{
|
|
printf("allocs %i\n", self->allocs);
|
|
printf("reallocs %i\n", self->reallocs);
|
|
printf("frees %i\n", self->frees);
|
|
printf("allocsMinusfrees %i\n", self->allocs - self->frees);
|
|
printf("allocatedBytes %i\n", self->allocatedBytes);
|
|
printf("maxAllocatedBytes %i\n", self->maxAllocatedBytes);
|
|
//printf("allocs %i bytes %i\n", self->allocs, self->allocatedBytes);
|
|
}
|
|
|
|
static Allocator *_globalAllocator;
|
|
|
|
Allocator *globalAllocator(void)
|
|
{
|
|
if(!_globalAllocator) Allocator_new();
|
|
return _globalAllocator;
|
|
}
|
|
*/
|
|
|
|
// -------------------------------------------------------
|
|
|
|
typedef struct MemoryBlock MemoryBlock;
|
|
|
|
struct MemoryBlock
|
|
{
|
|
size_t size;
|
|
size_t allocNum;
|
|
char *file;
|
|
int line;
|
|
MemoryBlock *next;
|
|
MemoryBlock *prev;
|
|
char padding[40 - (sizeof(size_t) + sizeof(size_t) + sizeof(char *) + sizeof(int) + sizeof(void *) + sizeof(void *))];
|
|
};
|
|
|
|
MemoryBlock *PtrToMemoryBlock(void *ptr)
|
|
{
|
|
return (MemoryBlock *)(((char *)ptr) - sizeof(MemoryBlock));
|
|
}
|
|
|
|
void *MemoryBlockToPtr(MemoryBlock *self)
|
|
{
|
|
return (void *)(((char *)self) + sizeof(MemoryBlock));
|
|
}
|
|
|
|
static MemoryBlock *_baseblock = NULL;
|
|
|
|
//inline
|
|
MemoryBlock *baseblock(void)
|
|
{
|
|
if(!_baseblock) _baseblock = calloc(1, sizeof(MemoryBlock));
|
|
return _baseblock;
|
|
}
|
|
|
|
void MemoryBlock_remove(MemoryBlock *self)
|
|
{
|
|
if (self->next) self->next->prev = self->prev;
|
|
if (self->prev) self->prev->next = self->next;
|
|
}
|
|
|
|
void MemoryBlock_insertAfter_(MemoryBlock *self, MemoryBlock *other)
|
|
{
|
|
self->next = other->next;
|
|
self->prev = other;
|
|
other->next = self;
|
|
if (self->next) self->next->prev = self;
|
|
}
|
|
|
|
MemoryBlock *MemoryBlock_newWithSize_file_line_(size_t size, char *file, int line)
|
|
{
|
|
MemoryBlock *self = calloc(1, sizeof(MemoryBlock) + size);
|
|
self->size = size;
|
|
self->allocNum = allocs;
|
|
self->file = file;
|
|
self->line = line;
|
|
MemoryBlock_insertAfter_(self, baseblock());
|
|
|
|
allocs ++;
|
|
allocatedBytes += size;
|
|
if (allocatedBytes > maxAllocatedBytes) maxAllocatedBytes = allocatedBytes;
|
|
return self;
|
|
}
|
|
|
|
MemoryBlock *MemoryBlock_reallocToSize_(MemoryBlock *self, size_t size)
|
|
{
|
|
MemoryBlock *prev = self->prev;
|
|
MemoryBlock_remove(self);
|
|
allocatedBytes -= self->size;
|
|
allocatedBytes += size;
|
|
reallocs ++;
|
|
self = realloc(self, sizeof(MemoryBlock) + size);
|
|
self->size = size;
|
|
MemoryBlock_insertAfter_(self, prev);
|
|
return self;
|
|
}
|
|
|
|
void MemoryBlock_free(MemoryBlock *self)
|
|
{
|
|
MemoryBlock_remove(self);
|
|
allocatedBytes -= self->size;
|
|
frees ++;
|
|
free(self);
|
|
}
|
|
|
|
size_t MemoryBlock_size(MemoryBlock *self)
|
|
{
|
|
return self->size;
|
|
}
|
|
|
|
void MemoryBlock_show(MemoryBlock *self)
|
|
{
|
|
char *file = strrchr(self->file, '/');
|
|
file = file ? file + 1 : self->file;
|
|
//printf(" MemoryBlock %p:\n", (void *)self);
|
|
//printf("\tsize %i\n", self->size);
|
|
//printf("\tfile %s\n", file);
|
|
//printf("\tline %i\n", self->line);
|
|
printf("\t%i %p %s:%i\t\t%i bytes\n", self->allocNum, MemoryBlockToPtr(self), file, self->line, self->size);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void *io_real_malloc(size_t size, char *file, int line)
|
|
{
|
|
MemoryBlock *m = MemoryBlock_newWithSize_file_line_(size, file, line);
|
|
return MemoryBlockToPtr(m);
|
|
}
|
|
|
|
void *io_real_calloc(size_t count, size_t size, char *file, int line)
|
|
{
|
|
return io_real_malloc(count * size, file, line);
|
|
}
|
|
|
|
void *io_real_realloc(void *ptr, size_t size, char *file, int line)
|
|
{
|
|
if (ptr)
|
|
{
|
|
MemoryBlock *m = MemoryBlock_reallocToSize_(PtrToMemoryBlock(ptr), size);
|
|
return MemoryBlockToPtr(m);
|
|
}
|
|
|
|
return io_real_malloc(size, file, line);
|
|
}
|
|
|
|
void io_free(void *ptr)
|
|
{
|
|
MemoryBlock_free(PtrToMemoryBlock(ptr));
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
void io_show_mem(char *s)
|
|
{
|
|
printf("\n--- %s ---\n", s ? s : "");
|
|
printf("allocs %i\n", allocs);
|
|
printf("reallocs %i\n", reallocs);
|
|
printf("frees %i\n", frees);
|
|
printf("allocsMinusfrees %i\n", allocs - frees);
|
|
printf("allocatedBytes %i\n", allocatedBytes);
|
|
printf("maxAllocatedBytes %i\n", maxAllocatedBytes);
|
|
//printf("allocs %i bytes %i\n", allocs, allocatedBytes);
|
|
//printf("\n");
|
|
}
|
|
|
|
size_t io_maxAllocatedBytes(void)
|
|
{
|
|
return maxAllocatedBytes;
|
|
}
|
|
|
|
void io_resetMaxAllocatedBytes(void)
|
|
{
|
|
maxAllocatedBytes = allocatedBytes;
|
|
}
|
|
|
|
size_t io_frees(void)
|
|
{
|
|
return frees;
|
|
}
|
|
|
|
size_t io_allocatedBytes(void)
|
|
{
|
|
return allocatedBytes;
|
|
}
|
|
|
|
size_t io_allocs(void)
|
|
{
|
|
return allocs;
|
|
}
|
|
|
|
void io_showUnfreed(void)
|
|
{
|
|
MemoryBlock *m = baseblock()->next;
|
|
size_t sum = 0;
|
|
int n = 0;
|
|
|
|
while (m)
|
|
{
|
|
MemoryBlock_show(m);
|
|
sum += m->size;
|
|
n ++;
|
|
m = m->next;
|
|
}
|
|
|
|
printf("\n %i bytes in %i blocks\n", (int)sum, n);
|
|
}
|
|
|
|
#endif
|
|
|
|
void *cpalloc(const void *p, size_t size)
|
|
{
|
|
void *n = io_malloc(size);
|
|
if(p) memcpy(n, p, size);
|
|
return n;
|
|
}
|
|
|
|
void *io_freerealloc(void *p, size_t size)
|
|
{
|
|
return realloc(p, size);
|
|
/*
|
|
void *n = io_malloc(size);
|
|
|
|
if (p != NULL)
|
|
{
|
|
memcpy(n, p, size);
|
|
free(p);
|
|
}
|
|
|
|
return n;
|
|
*/
|
|
}
|
|
|
|
int io_isBigEndian(void)
|
|
{
|
|
int i = 0x1;
|
|
uint8_t *s = (uint8_t *)(&i);
|
|
return s[0];
|
|
}
|
|
|
|
uint32_t io_uint32InBigEndian(uint32_t i)
|
|
{
|
|
uint32_t o;
|
|
uint8_t *os = (uint8_t *)&o;
|
|
uint8_t *is = (uint8_t *)&i;
|
|
if (io_isBigEndian()) return i;
|
|
os[0] = is[3];
|
|
os[1] = is[2];
|
|
os[2] = is[1];
|
|
os[3] = is[0];
|
|
return o;
|
|
}
|
|
|