mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[util] Use mmap/munmap for cmem internal alloc/free
This reduces the overhead needed to manage the memory blocks as the blocks are guaranteed to be page-aligned. Also, the superblock is now alllocated from within one of the memory blocks it manages. While this does slightly reduce the available cachelines within the first block (by one or two depending on 32 vs 64 bit pointers), it removes the need for an extra memory allocation (probably via malloc) for the superblock.
This commit is contained in:
parent
12450fe6b8
commit
0a847f92f1
6 changed files with 158 additions and 153 deletions
|
@ -60,20 +60,11 @@ typedef struct memsline_s {
|
|||
typedef struct memblock_s {
|
||||
struct memblock_s *next;
|
||||
struct memblock_s **prev;
|
||||
/* The pointer to pass to free()
|
||||
*/
|
||||
void *mem;
|
||||
memline_t *free_lines;
|
||||
/* Size of memory region before block "header".
|
||||
*
|
||||
* Since large blocks are allocated with page-size alignment, odds are
|
||||
* high that the there will be many cache lines "wasted" in the space
|
||||
* between the address returned from aligned_alloc (to cache-line
|
||||
* alignment) and the block itself. Setting them up as a pool makes the
|
||||
* lines available for smaller allocations, thus reducing waste.
|
||||
/* Size of memory available within the page-sized block.
|
||||
*/
|
||||
size_t pre_size;
|
||||
/* Size of memory region after block "header".
|
||||
size_t size;
|
||||
/* Size of memory region after the page-sized block.
|
||||
*
|
||||
* Will be 0 for blocks that were allocated exclusively for small
|
||||
* allocations, otherwise indicates the size of the allocated block.
|
||||
|
@ -85,7 +76,7 @@ typedef struct memblock_s {
|
|||
#if __WORDSIZE == 64
|
||||
int pad;
|
||||
#endif
|
||||
size_t pre_allocated;
|
||||
size_t allocated;
|
||||
} __attribute__((aligned (64))) memblock_t;
|
||||
|
||||
typedef struct memsuper_s {
|
||||
|
|
|
@ -123,6 +123,7 @@ void Sys_MakeCodeWriteable (uintptr_t startaddr, size_t length);
|
|||
void Sys_PageIn (void *ptr, size_t size);
|
||||
long Sys_PageSize (void);
|
||||
void *Sys_Alloc (size_t size);
|
||||
void Sys_Free (void *mem, size_t size);
|
||||
|
||||
//
|
||||
// system IO
|
||||
|
|
139
libs/util/cmem.c
139
libs/util/cmem.c
|
@ -28,21 +28,10 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/cmem.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define cmem_alloc(align, size) _aligned_malloc(size, align)
|
||||
#define cmem_free(mem) _aligned_free(mem)
|
||||
#else
|
||||
#define cmem_alloc(align, size) aligned_alloc(align, size)
|
||||
#define cmem_free(mem) free(mem)
|
||||
#endif
|
||||
|
||||
static size_t __attribute__((const))
|
||||
ilog2 (size_t x)
|
||||
{
|
||||
|
@ -53,27 +42,6 @@ ilog2 (size_t x)
|
|||
return l;
|
||||
}
|
||||
|
||||
memsuper_t *
|
||||
new_memsuper (void)
|
||||
{
|
||||
memsuper_t *super = cmem_alloc (MEM_LINE_SIZE, sizeof (*super));
|
||||
memset (super, 0, sizeof (*super));
|
||||
super->page_size = Sys_PageSize ();
|
||||
super->page_mask = (super->page_size - 1);
|
||||
return super;
|
||||
}
|
||||
|
||||
void
|
||||
delete_memsuper (memsuper_t *super)
|
||||
{
|
||||
while (super->memblocks) {
|
||||
memblock_t *t = super->memblocks;
|
||||
super->memblocks = super->memblocks->next;
|
||||
cmem_free (t->mem);
|
||||
}
|
||||
cmem_free (super);
|
||||
}
|
||||
|
||||
static void
|
||||
link_free_line (memsuper_t *super, memline_t *line)
|
||||
{
|
||||
|
@ -109,12 +77,8 @@ unlink_line (memline_t *line)
|
|||
static memblock_t *
|
||||
init_block (memsuper_t *super, void *mem, size_t alloc_size)
|
||||
{
|
||||
size_t size = super->page_size;
|
||||
size_t mask = super->page_mask;
|
||||
size_t ptr = (size_t) mem;
|
||||
memblock_t *block;
|
||||
memblock_t *block = mem;
|
||||
|
||||
block = (memblock_t *) (((ptr + size) & ~mask)) - 1;
|
||||
memset (block, 0, sizeof (memblock_t));
|
||||
|
||||
if (super->memblocks) {
|
||||
|
@ -124,26 +88,20 @@ init_block (memsuper_t *super, void *mem, size_t alloc_size)
|
|||
block->prev = &super->memblocks;
|
||||
super->memblocks = block;
|
||||
|
||||
block->mem = mem;
|
||||
block->pre_size = (size_t) block - (size_t) mem;
|
||||
block->post_size = alloc_size - block->pre_size - sizeof (memblock_t);
|
||||
if (!((size_t) mem & mask) && block->pre_size) {
|
||||
// can't use the first cache line of the page as it would be
|
||||
// indistinguishable from a large block
|
||||
block->pre_size -= MEM_LINE_SIZE;
|
||||
}
|
||||
if (block->pre_size) {
|
||||
memline_t *line = (memline_t *) ((size_t) block - block->pre_size);
|
||||
block->size = super->page_size - sizeof (*block);
|
||||
block->post_size = alloc_size - super->page_size;
|
||||
|
||||
line->block = block;
|
||||
line->size = block->pre_size;
|
||||
memline_t *line = (memline_t *) (block + 1);
|
||||
|
||||
line->block_next = 0;
|
||||
line->block_prev = &block->free_lines;
|
||||
block->free_lines = line;
|
||||
line->block = block;
|
||||
line->size = block->size;
|
||||
|
||||
line->block_next = 0;
|
||||
line->block_prev = &block->free_lines;
|
||||
block->free_lines = line;
|
||||
|
||||
link_free_line (super, line);
|
||||
|
||||
link_free_line (super, line);
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -167,8 +125,8 @@ block_alloc (memsuper_t *super, size_t size)
|
|||
}
|
||||
|
||||
size_t page_size = super->page_size;
|
||||
size_t alloc_size = sizeof (memblock_t) + page_size + size;
|
||||
void *mem = cmem_alloc (MEM_LINE_SIZE, alloc_size);
|
||||
size_t alloc_size = page_size + size;
|
||||
void *mem = Sys_Alloc (alloc_size);
|
||||
block = init_block (super, mem, alloc_size);
|
||||
return block;
|
||||
}
|
||||
|
@ -199,7 +157,7 @@ alloc_line (memline_t *line, size_t size)
|
|||
line->free_next = split;
|
||||
split->free_prev = &line->free_next;
|
||||
}
|
||||
line->block->pre_allocated += line->size;
|
||||
line->block->allocated += line->size;
|
||||
unlink_line (line);
|
||||
return mem;
|
||||
}
|
||||
|
@ -213,7 +171,7 @@ line_free (memsuper_t *super, memblock_t *block, void *mem)
|
|||
memline_t **l;
|
||||
memline_t *line = 0;
|
||||
|
||||
block->pre_allocated -= size;
|
||||
block->allocated -= size;
|
||||
|
||||
for (l = &block->free_lines; *l; l = &(*l)->block_next) {
|
||||
line = *l;
|
||||
|
@ -303,7 +261,7 @@ cmemalloc (memsuper_t *super, size_t size)
|
|||
if (!block) {
|
||||
return 0;
|
||||
}
|
||||
return block + 1;
|
||||
return (void *) ((size_t) block + super->page_size);
|
||||
} else {
|
||||
size = 4 << ind;
|
||||
if (size >= MEM_LINE_SIZE) {
|
||||
|
@ -328,7 +286,7 @@ cmemalloc (memsuper_t *super, size_t size)
|
|||
* allocated line is ever page-aligned as that would make the
|
||||
* line indistinguishable from a large block.
|
||||
*/
|
||||
mem = cmem_alloc (super->page_size, super->page_size);
|
||||
mem = Sys_Alloc (super->page_size);
|
||||
// sets super->free_lines, the block is guarnateed to be big
|
||||
// enough to hold the requested allocation as otherwise a full
|
||||
// block allocation would have been used
|
||||
|
@ -368,12 +326,11 @@ cmemalloc (memsuper_t *super, size_t size)
|
|||
static void
|
||||
unlink_block (memblock_t *block)
|
||||
{
|
||||
if (block->pre_size) {
|
||||
if (!block->free_lines || block->free_lines->block_next) {
|
||||
*(int *) 0 = 0;
|
||||
}
|
||||
unlink_line (block->free_lines);
|
||||
if (!block->free_lines || block->free_lines->block_next) {
|
||||
*(int *) 0 = 0;
|
||||
}
|
||||
unlink_line (block->free_lines);
|
||||
|
||||
if (block->next) {
|
||||
block->next->prev = block->prev;
|
||||
}
|
||||
|
@ -411,17 +368,57 @@ cmemfree (memsuper_t *super, void *mem)
|
|||
return;
|
||||
} else if ((size_t) mem & super->page_mask) {
|
||||
// cache line
|
||||
size_t page_size = super->page_size;
|
||||
size_t page_mask = super->page_mask;
|
||||
block = (memblock_t *) (((size_t) mem + page_size) & ~page_mask) - 1;
|
||||
block = (memblock_t *) ((size_t) mem & ~super->page_mask);
|
||||
line_free (super, block, mem);
|
||||
} else {
|
||||
// large block
|
||||
block = (memblock_t *) mem - 1;
|
||||
block = (memblock_t *) ((size_t) mem - super->page_size);
|
||||
block->post_free = 1;
|
||||
}
|
||||
if (!block->pre_allocated && (!block->post_size || block->post_free)) {
|
||||
if (!block->allocated && (!block->post_size || block->post_free)) {
|
||||
unlink_block (block);
|
||||
cmem_free (block->mem);
|
||||
Sys_Free (block, super->page_size + block->post_size);
|
||||
}
|
||||
}
|
||||
|
||||
memsuper_t *
|
||||
new_memsuper (void)
|
||||
{
|
||||
// Temporary superblock used to bootstrap a pool
|
||||
memsuper_t bootstrap = { };
|
||||
bootstrap.page_size = Sys_PageSize ();
|
||||
bootstrap.page_mask = (bootstrap.page_size - 1);
|
||||
|
||||
// Allocate the real superblock from the pool. As a superblock is only
|
||||
// two cache lines large (for 64-byte cache lines), it will always be
|
||||
// allocated using a block's cache lines, and thus will be inside the first
|
||||
// block.
|
||||
memsuper_t *super = cmemalloc (&bootstrap, sizeof (*super));
|
||||
*super = bootstrap;
|
||||
// The block used to allocate the real superblock points to the bootstrap
|
||||
// superblock, but needs to point to the real superblock.
|
||||
super->memblocks->prev = &super->memblocks;
|
||||
|
||||
// Any free cache line block chains will also point to the bootstrap
|
||||
// block instead of the resl superblock, so fix them up too (there should
|
||||
// be only one, but no harm in being paranoid)
|
||||
for (int i = 0; i < MAX_CACHE_LINES; i++) {
|
||||
if (super->free_lines[i]) {
|
||||
super->free_lines[i]->free_prev = &super->free_lines[i];
|
||||
}
|
||||
}
|
||||
return super;
|
||||
}
|
||||
|
||||
void
|
||||
delete_memsuper (memsuper_t *super)
|
||||
{
|
||||
// The block holding the superblock is always the last block in the list
|
||||
while (super->memblocks && super->memblocks->next) {
|
||||
memblock_t *t = super->memblocks;
|
||||
super->memblocks = super->memblocks->next;
|
||||
Sys_Free (t, super->page_size + t->post_size);
|
||||
}
|
||||
memblock_t *block = super->memblocks;
|
||||
Sys_Free (block, super->page_size + block->post_size);
|
||||
}
|
||||
|
|
|
@ -650,6 +650,19 @@ Sys_Alloc (size_t size)
|
|||
#endif
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Sys_Free (void *mem, size_t size)
|
||||
{
|
||||
size_t page_size = Sys_PageSize ();
|
||||
size_t page_mask = page_size - 1;
|
||||
size = (size + page_mask) & ~page_mask;
|
||||
#ifdef _WIN32
|
||||
# error implement Sys_Free for windows
|
||||
#else
|
||||
munmap (mem, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Sys_DebugLog (const char *file, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "QF/cmem.h"
|
||||
#include "QF/set.h"
|
||||
|
||||
#define SUPER_LINES (sizeof (memsuper_t) / MEM_LINE_SIZE)
|
||||
|
||||
static int
|
||||
test_block (memsuper_t *super)
|
||||
{
|
||||
|
@ -24,7 +26,7 @@ test_block (memsuper_t *super)
|
|||
return 0;
|
||||
}
|
||||
block = super->memblocks;
|
||||
if (mem != block + 1) {
|
||||
if ((size_t) mem != (size_t) block + super->page_size) {
|
||||
fprintf (stderr, "super does not point to mem\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,7 +42,7 @@ test_block (memsuper_t *super)
|
|||
}
|
||||
memset (mem, 0, size); // valgrind check
|
||||
cmemfree (super, mem);
|
||||
if (super->memblocks) {
|
||||
if ((size_t) super->memblocks + super->page_size == (size_t) mem) {
|
||||
fprintf (stderr, "super still points to mem\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -57,11 +59,11 @@ check_block (memblock_t *block, int line_count, int allocated)
|
|||
|
||||
for (memline_t **l = &block->free_lines; *l; l = &(*l)->block_next) {
|
||||
memline_t *line = *l;
|
||||
ptrdiff_t ind = (byte *) block - (byte *) line;
|
||||
ptrdiff_t ind = (byte *) line - (byte *) block;
|
||||
ind /= MEM_LINE_SIZE;
|
||||
if (ind < 1 || (size_t ) ind > block->pre_size / MEM_LINE_SIZE) {
|
||||
fprintf (stderr, "line outside of block: %p %p %p\n",
|
||||
line, block->mem, block);
|
||||
if (ind < 1 || (size_t ) (ind - 1) > block->size / MEM_LINE_SIZE) {
|
||||
fprintf (stderr, "line outside of block: %p %p\n",
|
||||
line, block);
|
||||
return 0;
|
||||
}
|
||||
if (set_is_member (visited, ind)) {
|
||||
|
@ -86,9 +88,9 @@ check_block (memblock_t *block, int line_count, int allocated)
|
|||
fprintf (stderr, "line block_prev link incorrect\n");
|
||||
ret = 0;
|
||||
}
|
||||
if (line->size > block->pre_size) {
|
||||
if (line->size > block->size) {
|
||||
fprintf (stderr, "line size too large: %zd / %zd\n",
|
||||
line->size, block->pre_size);
|
||||
line->size, block->size);
|
||||
ret = 0;
|
||||
}
|
||||
if (line->size % MEM_LINE_SIZE) {
|
||||
|
@ -101,9 +103,9 @@ check_block (memblock_t *block, int line_count, int allocated)
|
|||
}
|
||||
}
|
||||
if (ret) {
|
||||
if (free_bytes + block->pre_allocated != block->pre_size) {
|
||||
if (free_bytes + block->allocated != block->size) {
|
||||
fprintf (stderr, "block space mismatch: s: %zd a: %zd f: %zd\n",
|
||||
block->pre_size, block->pre_allocated, free_bytes);
|
||||
block->size, block->allocated, free_bytes);
|
||||
ret = 0;
|
||||
}
|
||||
if (line_count >= 0 && line_count != count) {
|
||||
|
@ -111,9 +113,9 @@ check_block (memblock_t *block, int line_count, int allocated)
|
|||
line_count, count);
|
||||
ret = 0;
|
||||
}
|
||||
if (allocated >= 0 && (size_t) allocated != block->pre_allocated) {
|
||||
fprintf (stderr, "pre_allocated wrong size: %zd != %d\n",
|
||||
block->pre_allocated, allocated);
|
||||
if (allocated >= 0 && (size_t) allocated != block->allocated) {
|
||||
fprintf (stderr, "allocated wrong size: %zd != %d\n",
|
||||
block->allocated, allocated);
|
||||
}
|
||||
}
|
||||
set_delete (visited);
|
||||
|
@ -188,19 +190,22 @@ test_line (memsuper_t *super)
|
|||
fprintf (stderr, "too many memblocks\n");
|
||||
return 0;
|
||||
}
|
||||
if (line1 < (memline_t *) block->mem || line1 >= (memline_t *) block) {
|
||||
fprintf (stderr, "line1 outside block line pool: %p %p %p\n",
|
||||
line1, block->mem, block);
|
||||
if (line1 < (memline_t *) (block + 1)
|
||||
|| line1 >= (memline_t *) ((byte *) block + super->page_size)) {
|
||||
fprintf (stderr, "line1 outside block line pool: %p %p\n",
|
||||
line1, block);
|
||||
return 0;
|
||||
}
|
||||
if (line2 < (memline_t *) block->mem || line2 >= (memline_t *) block) {
|
||||
fprintf (stderr, "line2 outside block line pool: %p %p %p\n",
|
||||
line2, block->mem, block);
|
||||
if (line2 < (memline_t *) (block + 1)
|
||||
|| line2 >= (memline_t *) ((byte *) block + super->page_size)) {
|
||||
fprintf (stderr, "line2 outside block line pool: %p %p\n",
|
||||
line2, block);
|
||||
return 0;
|
||||
}
|
||||
if (line3 < (memline_t *) block->mem || line3 >= (memline_t *) block) {
|
||||
fprintf (stderr, "line3 outside block line pool: %p %p %p\n",
|
||||
line3, block->mem, block);
|
||||
if (line3 < (memline_t *) (block + 1)
|
||||
|| line3 >= (memline_t *) ((byte *) block + super->page_size)) {
|
||||
fprintf (stderr, "line3 outside block line pool: %p %p\n",
|
||||
line3, block);
|
||||
return 0;
|
||||
}
|
||||
if (!((size_t) line1 & super->page_mask)) {
|
||||
|
@ -224,7 +229,7 @@ test_line (memsuper_t *super)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!check_block (block, 1, 3 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (3 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 1 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -235,7 +240,7 @@ test_line (memsuper_t *super)
|
|||
|
||||
cmemfree (super, line2);
|
||||
|
||||
if (!check_block (block, 2, 2 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 2, (2 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 2 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -254,7 +259,7 @@ test_line (memsuper_t *super)
|
|||
}
|
||||
|
||||
cmemfree (super, line3);
|
||||
if (!check_block (block, 1, 1 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (1 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 3 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -269,12 +274,17 @@ test_line (memsuper_t *super)
|
|||
}
|
||||
|
||||
cmemfree (super, line1);
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "line pool not freed\n");
|
||||
if (!check_block (block, 1, (0 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 4 failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (!check_bins (super, 0x00)) {
|
||||
fprintf (stderr, "bins not cleared\n");
|
||||
if (!check_bins (super, 0x20)) {
|
||||
fprintf (stderr, "bin check 4 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (super->free_lines[5] != line1) {
|
||||
fprintf (stderr, "super free_lines[5] not pointing to line1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -283,7 +293,7 @@ test_line (memsuper_t *super)
|
|||
line3 = cmemalloc (super, MEM_LINE_SIZE);
|
||||
block = super->memblocks;
|
||||
|
||||
if (!check_block (block, 1, 3 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (3 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 4 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -294,7 +304,7 @@ test_line (memsuper_t *super)
|
|||
|
||||
cmemfree (super, line1);
|
||||
|
||||
if (!check_block (block, 2, 2 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 2, (2 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 5 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -305,7 +315,7 @@ test_line (memsuper_t *super)
|
|||
|
||||
cmemfree (super, line2);
|
||||
|
||||
if (!check_block (block, 2, 1 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 2, (1 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 6 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,21 +325,13 @@ test_line (memsuper_t *super)
|
|||
}
|
||||
|
||||
cmemfree (super, line3);
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "line pool not freed 2\n");
|
||||
return 0;
|
||||
}
|
||||
if (!check_bins (super, 0x00)) {
|
||||
fprintf (stderr, "bins not cleared 2\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
line1 = cmemalloc (super, MEM_LINE_SIZE);
|
||||
line2 = cmemalloc (super, MEM_LINE_SIZE);
|
||||
line3 = cmemalloc (super, MEM_LINE_SIZE);
|
||||
block = super->memblocks;
|
||||
|
||||
if (!check_block (block, 1, 3 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (3 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 7 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -340,7 +342,7 @@ test_line (memsuper_t *super)
|
|||
|
||||
cmemfree (super, line3);
|
||||
|
||||
if (!check_block (block, 1, 2 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (2 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 8 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -351,7 +353,7 @@ test_line (memsuper_t *super)
|
|||
|
||||
cmemfree (super, line2);
|
||||
|
||||
if (!check_block (block, 1, 1 * MEM_LINE_SIZE)) {
|
||||
if (!check_block (block, 1, (1 + SUPER_LINES) * MEM_LINE_SIZE)) {
|
||||
fprintf (stderr, "line block check 9 failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -361,14 +363,6 @@ test_line (memsuper_t *super)
|
|||
}
|
||||
|
||||
cmemfree (super, line1);
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "line pool not freed 3\n");
|
||||
return 0;
|
||||
}
|
||||
if (!check_bins (super, 0x00)) {
|
||||
fprintf (stderr, "bins not cleared 3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -481,16 +475,16 @@ test_block_line (memsuper_t *super)
|
|||
void *line;
|
||||
memblock_t *block = super->memblocks;
|
||||
|
||||
if (block + 1 != (memblock_t *) mem) {
|
||||
if ((size_t) block + super->page_size != (size_t) mem) {
|
||||
fprintf (stderr, "super memblocks do not point to mem\n");
|
||||
return 0;
|
||||
}
|
||||
if (block->pre_size < MEM_LINE_SIZE) {
|
||||
if (block->size < MEM_LINE_SIZE) {
|
||||
// need to figure out a way to guarantee a shared block
|
||||
fprintf (stderr, "can't allocate line from block\n");
|
||||
return 0;
|
||||
}
|
||||
if (block->next) {
|
||||
if (block->next != (memblock_t *) ((size_t) super & ~super->page_mask)) {
|
||||
fprintf (stderr, "excess blocks in super\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,7 +493,7 @@ test_block_line (memsuper_t *super)
|
|||
fprintf (stderr, "line is page aligned\n");
|
||||
return 0;
|
||||
}
|
||||
if (super->memblocks->next) {
|
||||
if (0 && super->memblocks->next) {
|
||||
// need to figure out a way to guarantee a shared block
|
||||
fprintf (stderr, "mem and line not in same block\n");
|
||||
return 0;
|
||||
|
@ -513,7 +507,9 @@ test_block_line (memsuper_t *super)
|
|||
fprintf (stderr, "block not reused for mem\n");
|
||||
return 0;
|
||||
}
|
||||
if (super->memblocks != block || super->memblocks->next) {
|
||||
//if (super->memblocks != block || super->memblocks->next) {
|
||||
if (super->memblocks != block || !super->memblocks->next
|
||||
|| super->memblocks->next->next) {
|
||||
// need to figure out a way to guarantee a shared block
|
||||
fprintf (stderr, "blocks corrupt\n");
|
||||
return 0;
|
||||
|
@ -524,7 +520,7 @@ test_block_line (memsuper_t *super)
|
|||
return 0;
|
||||
}
|
||||
cmemfree (super, mem);
|
||||
if (super->memblocks) {
|
||||
if (0 && super->memblocks) {
|
||||
fprintf (stderr, "shared block not freed\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -588,8 +584,9 @@ main (void)
|
|||
super->page_mask);
|
||||
return 1;
|
||||
}
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "super block list not null\n");
|
||||
if (super->memblocks
|
||||
!= (memblock_t *) ((size_t) super & ~super->page_mask)) {
|
||||
fprintf (stderr, "superblock not in block a: %p %p\n", super->memblocks, super);
|
||||
return 1;
|
||||
}
|
||||
for (i = 4; i-- > 0; ) {
|
||||
|
@ -601,6 +598,7 @@ main (void)
|
|||
fprintf (stderr, "super last_freed not all null\n");
|
||||
return 1;
|
||||
}
|
||||
#if 0 // no longer valid
|
||||
for (i = MAX_CACHE_LINES; i-- > 0; ) {
|
||||
if (super->free_lines[i]) {
|
||||
break;
|
||||
|
@ -610,12 +608,14 @@ main (void)
|
|||
fprintf (stderr, "super free_lines not all null\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
if (!test_block (super)) {
|
||||
fprintf (stderr, "block tests failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "super block list not null 2\n");
|
||||
if (super->memblocks
|
||||
!= (memblock_t *) ((size_t) super & ~super->page_mask)) {
|
||||
fprintf (stderr, "superblock not in block b: %p %p\n", super->memblocks, super);
|
||||
return 1;
|
||||
}
|
||||
for (i = 4; i-- > 0; ) {
|
||||
|
@ -627,6 +627,7 @@ main (void)
|
|||
fprintf (stderr, "super last_freed not all null 2\n");
|
||||
return 1;
|
||||
}
|
||||
#if 0 // no longer valid
|
||||
for (i = MAX_CACHE_LINES; i-- > 0; ) {
|
||||
if (super->free_lines[i]) {
|
||||
break;
|
||||
|
@ -636,12 +637,14 @@ main (void)
|
|||
fprintf (stderr, "super free_lines not all null 2\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
if (!test_line (super)) {
|
||||
fprintf (stderr, "line tests failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (super->memblocks) {
|
||||
fprintf (stderr, "super block list not null 2\n");
|
||||
if (super->memblocks
|
||||
!= (memblock_t *) ((size_t) super & ~super->page_mask)) {
|
||||
fprintf (stderr, "superblock not in block c: %p %p\n", super->memblocks, super);
|
||||
return 1;
|
||||
}
|
||||
if (!test_block_line (super)) {
|
||||
|
|
|
@ -518,8 +518,8 @@ PortalCompleted (threaddata_t *thread, portal_t *completed)
|
|||
static void
|
||||
dump_super_stats (int id, memsuper_t *super)
|
||||
{
|
||||
size_t total_pre_size = 0;
|
||||
size_t total_pre_allocated = 0;
|
||||
size_t total_size = 0;
|
||||
size_t total_allocated = 0;
|
||||
size_t total_post_size = 0;
|
||||
size_t total_post_allocated = 0;
|
||||
size_t num_blocks = 0;
|
||||
|
@ -527,8 +527,8 @@ dump_super_stats (int id, memsuper_t *super)
|
|||
|
||||
for (memblock_t *block = super->memblocks; block; block = block->next) {
|
||||
num_blocks++;
|
||||
total_pre_size += block->pre_size;
|
||||
total_pre_allocated += block->pre_allocated;
|
||||
total_size += block->size;
|
||||
total_allocated += block->allocated;
|
||||
total_post_size += block->post_size;
|
||||
// post_free is a flag
|
||||
total_post_allocated += !block->post_free * block->post_size;
|
||||
|
@ -544,8 +544,8 @@ dump_super_stats (int id, memsuper_t *super)
|
|||
WRLOCK (global_lock);
|
||||
printf ("cmem stats for thread %d\n", id);
|
||||
printf (" blocks: %zd\n", num_blocks);
|
||||
printf (" pre: s:%-8zd a:%-8zd f:%-8zd\n", total_pre_size,
|
||||
total_pre_allocated, total_pre_size - total_pre_allocated);
|
||||
printf (" : s:%-8zd a:%-8zd f:%-8zd\n", total_size,
|
||||
total_allocated, total_size - total_allocated);
|
||||
printf (" post: s:%-8zd a:%-8zd f:%-8zd\n", total_post_size,
|
||||
total_post_allocated, total_post_size - total_post_allocated);
|
||||
printf (" ");
|
||||
|
|
Loading…
Reference in a new issue