2004-06-15 15:18:33 +00:00
|
|
|
#include <stdio.h>
|
2004-06-08 23:54:24 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "memblock.h"
|
|
|
|
|
|
2004-06-18 17:12:50 +00:00
|
|
|
unsigned memblock_count = 0, memblock_total = 0;
|
2004-06-15 15:18:33 +00:00
|
|
|
|
2004-06-08 23:54:24 +00:00
|
|
|
struct memblock *memblock_new(size_t length) {
|
|
|
|
|
struct memblock *b = malloc(sizeof(struct memblock)+length);
|
|
|
|
|
b->type = MEMBLOCK_APPENDED;
|
|
|
|
|
b->ref = 1;
|
|
|
|
|
b->length = length;
|
|
|
|
|
b->data = b+1;
|
2004-06-18 17:12:50 +00:00
|
|
|
memblock_count++;
|
|
|
|
|
memblock_total += length;
|
2004-06-08 23:54:24 +00:00
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct memblock *memblock_new_fixed(void *d, size_t length) {
|
|
|
|
|
struct memblock *b = malloc(sizeof(struct memblock));
|
|
|
|
|
b->type = MEMBLOCK_FIXED;
|
|
|
|
|
b->ref = 1;
|
|
|
|
|
b->length = length;
|
|
|
|
|
b->data = d;
|
2004-06-18 17:12:50 +00:00
|
|
|
memblock_count++;
|
|
|
|
|
memblock_total += length;
|
2004-06-08 23:54:24 +00:00
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct memblock *memblock_new_dynamic(void *d, size_t length) {
|
|
|
|
|
struct memblock *b = malloc(sizeof(struct memblock));
|
|
|
|
|
b->type = MEMBLOCK_DYNAMIC;
|
|
|
|
|
b->ref = 1;
|
|
|
|
|
b->length = length;
|
|
|
|
|
b->data = d;
|
2004-06-18 17:12:50 +00:00
|
|
|
memblock_count++;
|
|
|
|
|
memblock_total += length;
|
2004-06-08 23:54:24 +00:00
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct memblock* memblock_ref(struct memblock*b) {
|
|
|
|
|
assert(b && b->ref >= 1);
|
|
|
|
|
b->ref++;
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void memblock_unref(struct memblock*b) {
|
|
|
|
|
assert(b && b->ref >= 1);
|
|
|
|
|
b->ref--;
|
|
|
|
|
|
|
|
|
|
if (b->ref == 0) {
|
|
|
|
|
if (b->type == MEMBLOCK_DYNAMIC)
|
|
|
|
|
free(b->data);
|
2004-06-18 17:12:50 +00:00
|
|
|
|
|
|
|
|
memblock_count--;
|
|
|
|
|
memblock_total -= b->length;
|
|
|
|
|
|
2004-06-08 23:54:24 +00:00
|
|
|
free(b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void memblock_unref_fixed(struct memblock *b) {
|
|
|
|
|
void *d;
|
|
|
|
|
|
|
|
|
|
assert(b && b->ref >= 1);
|
|
|
|
|
|
|
|
|
|
if (b->ref == 1) {
|
|
|
|
|
memblock_unref(b);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d = malloc(b->length);
|
|
|
|
|
assert(d);
|
|
|
|
|
memcpy(d, b->data, b->length);
|
|
|
|
|
b->data = d;
|
|
|
|
|
b->type = MEMBLOCK_DYNAMIC;
|
|
|
|
|
}
|
|
|
|
|
|