foundationdb/fdbrpc/libcoroutine/Common.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;
}