dbghelp: Fix pool allocation routines to be able to support arbitrary sizes.
Also move full arenas to a separate list to avoid searching through them again and again.
This commit is contained in:
parent
55d6f07e31
commit
ae7490d362
|
@ -29,6 +29,7 @@
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "oaidl.h"
|
#include "oaidl.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
#include "cvconst.h"
|
#include "cvconst.h"
|
||||||
|
@ -37,13 +38,14 @@
|
||||||
|
|
||||||
struct pool /* poor's man */
|
struct pool /* poor's man */
|
||||||
{
|
{
|
||||||
struct pool_arena* first;
|
struct list arena_list;
|
||||||
unsigned arena_size;
|
struct list arena_full;
|
||||||
|
size_t arena_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
void pool_init(struct pool* a, unsigned arena_size);
|
void pool_init(struct pool* a, size_t arena_size);
|
||||||
void pool_destroy(struct pool* a);
|
void pool_destroy(struct pool* a);
|
||||||
void* pool_alloc(struct pool* a, unsigned len);
|
void* pool_alloc(struct pool* a, size_t len);
|
||||||
char* pool_strdup(struct pool* a, const char* str);
|
char* pool_strdup(struct pool* a, const char* str);
|
||||||
|
|
||||||
struct vector
|
struct vector
|
||||||
|
|
|
@ -34,14 +34,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
||||||
|
|
||||||
struct pool_arena
|
struct pool_arena
|
||||||
{
|
{
|
||||||
struct pool_arena* next;
|
struct list entry;
|
||||||
char* current;
|
char *current;
|
||||||
|
char *end;
|
||||||
};
|
};
|
||||||
|
|
||||||
void pool_init(struct pool* a, unsigned arena_size)
|
void pool_init(struct pool* a, size_t arena_size)
|
||||||
{
|
{
|
||||||
|
list_init( &a->arena_list );
|
||||||
|
list_init( &a->arena_full );
|
||||||
a->arena_size = arena_size;
|
a->arena_size = arena_size;
|
||||||
a->first = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pool_destroy(struct pool* pool)
|
void pool_destroy(struct pool* pool)
|
||||||
|
@ -50,58 +52,73 @@ void pool_destroy(struct pool* pool)
|
||||||
struct pool_arena* next;
|
struct pool_arena* next;
|
||||||
|
|
||||||
#ifdef USE_STATS
|
#ifdef USE_STATS
|
||||||
unsigned alloc, used, num;
|
size_t alloc, used, num;
|
||||||
|
|
||||||
alloc = used = num = 0;
|
alloc = used = num = 0;
|
||||||
arena = pool->first;
|
LIST_FOR_EACH_ENTRY( arena, &pool->arena_list, struct pool_arena, entry )
|
||||||
while (arena)
|
|
||||||
{
|
{
|
||||||
alloc += pool->arena_size;
|
alloc += arena->end - (char *)arena;
|
||||||
|
used += arena->current - (char*)arena;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
LIST_FOR_EACH_ENTRY( arena, &pool->arena_full, struct pool_arena, entry )
|
||||||
|
{
|
||||||
|
alloc += arena->end - (char *)arena;
|
||||||
used += arena->current - (char*)arena;
|
used += arena->current - (char*)arena;
|
||||||
num++;
|
num++;
|
||||||
arena = arena->next;
|
|
||||||
}
|
}
|
||||||
if (alloc == 0) alloc = 1; /* avoid division by zero */
|
if (alloc == 0) alloc = 1; /* avoid division by zero */
|
||||||
FIXME("STATS: pool %p has allocated %u kbytes, used %u kbytes in %u arenas,\n"
|
FIXME("STATS: pool %p has allocated %u kbytes, used %u kbytes in %u arenas, non-allocation ratio: %.2f%%\n",
|
||||||
"\t\t\t\tnon-allocation ratio: %.2f%%\n",
|
pool, (unsigned)(alloc >> 10), (unsigned)(used >> 10), (unsigned)num,
|
||||||
pool, alloc >> 10, used >> 10, num, 100.0 - (float)used / (float)alloc * 100.0);
|
100.0 - (float)used / (float)alloc * 100.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
arena = pool->first;
|
LIST_FOR_EACH_ENTRY_SAFE( arena, next, &pool->arena_list, struct pool_arena, entry )
|
||||||
while (arena)
|
|
||||||
{
|
{
|
||||||
next = arena->next;
|
list_remove( &arena->entry );
|
||||||
|
HeapFree(GetProcessHeap(), 0, arena);
|
||||||
|
}
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE( arena, next, &pool->arena_full, struct pool_arena, entry )
|
||||||
|
{
|
||||||
|
list_remove( &arena->entry );
|
||||||
HeapFree(GetProcessHeap(), 0, arena);
|
HeapFree(GetProcessHeap(), 0, arena);
|
||||||
arena = next;
|
|
||||||
}
|
}
|
||||||
pool_init(pool, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pool_alloc(struct pool* pool, unsigned len)
|
void* pool_alloc(struct pool* pool, size_t len)
|
||||||
{
|
{
|
||||||
struct pool_arena* arena;
|
struct pool_arena* arena;
|
||||||
void* ret;
|
void* ret;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
len = (len + 3) & ~3; /* round up size on DWORD boundary */
|
len = (len + 3) & ~3; /* round up size on DWORD boundary */
|
||||||
assert(sizeof(struct pool_arena) + len <= pool->arena_size && len);
|
|
||||||
|
|
||||||
for (arena = pool->first; arena; arena = arena->next)
|
LIST_FOR_EACH_ENTRY( arena, &pool->arena_list, struct pool_arena, entry )
|
||||||
{
|
{
|
||||||
if ((char*)arena + pool->arena_size - arena->current >= len)
|
if (arena->end - arena->current >= len)
|
||||||
{
|
{
|
||||||
ret = arena->current;
|
ret = arena->current;
|
||||||
arena->current += len;
|
arena->current += len;
|
||||||
|
if (arena->current + 16 >= arena->end)
|
||||||
|
{
|
||||||
|
list_remove( &arena->entry );
|
||||||
|
list_add_tail( &pool->arena_full, &arena->entry );
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arena = HeapAlloc(GetProcessHeap(), 0, pool->arena_size);
|
size = max( pool->arena_size, len + sizeof(struct pool_arena) );
|
||||||
if (!arena) {ERR("OOM\n");return NULL;}
|
arena = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
if (!arena) {ERR("OOM for %u\n", size);return NULL;}
|
||||||
|
|
||||||
ret = (char*)arena + sizeof(*arena);
|
ret = arena + 1;
|
||||||
arena->next = pool->first;
|
|
||||||
pool->first = arena;
|
|
||||||
arena->current = (char*)ret + len;
|
arena->current = (char*)ret + len;
|
||||||
|
arena->end = (char *)arena + size;
|
||||||
|
if (arena->current + 16 >= arena->end)
|
||||||
|
list_add_tail( &pool->arena_full, &arena->entry );
|
||||||
|
else
|
||||||
|
list_add_head( &pool->arena_list, &arena->entry );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue