foundationdb/fdbrpc/libcoroutine/Common.c

290 lines
6.3 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;
}