1
1
forked from 0ad/0ad

fixed alignment (broken after last user_p change)

This was SVN commit r949.
This commit is contained in:
janwas 2004-08-09 16:44:42 +00:00
parent 1768ccded3
commit 687aea271e
2 changed files with 34 additions and 41 deletions

View File

@ -12,18 +12,17 @@
#include <map>
struct Mem
{
// what is reported by mem_get_ptr / mem_size
void* user_p;
size_t user_size;
// initially what mem_alloc returns; can be changed via mem_assign_user
void* p;
size_t size;
// actual allocation params (set by allocator)
// unaligned mem from allocator
void* raw_p;
size_t raw_size;
uintptr_t ctx;
uintptr_t ctx;
MEM_DTOR dtor; // this allows user-specified dtors.
};
@ -53,12 +52,11 @@ static int Mem_reload(Mem* /*m*/, const char* /*fn*/, Handle /*h*/)
//////////////////////////////////////////////////////////////////////////////
// "raw_*": memory requested from allocator (+ padding for alignment
// requested by mem_alloc)
// "user_*": same as raw, until someones changes it via {?}
// "*": aligned memory returned by allocator.
// "user_*": same as above, until someones changes it via mem_assign_user
// allocator interface:
// alloc: return at least raw_size bytes of memory (alignment done by caller)
// alloc: return at least size bytes of memory (alignment done by caller)
//////////////////////////////////////////////////////////////////////////////
@ -188,7 +186,7 @@ static Handle find_alloc(void* target_p)
if(m)
{
// found it within this mem range.
if(target_p <= (char*)m->raw_p + m->raw_size)
if(target_p <= (char*)m->p + m->size)
return hm;
}
}
@ -247,30 +245,30 @@ int mem_free_h(Handle& hm)
}
Handle mem_assign(void* raw_p, size_t raw_size, uint flags /* = 0 */, MEM_DTOR dtor /* = 0 */, uintptr_t ctx /* = 0 */)
Handle mem_assign(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx)
{
// we've already allocated that pointer - returns its handle
Handle hm = find_alloc(raw_p);
Handle hm = find_alloc(p);
if(hm > 0)
return hm;
if(!raw_p || !raw_size)
if(!p || !size)
{
debug_warn("mem_assign: invalid p or size");
return 0;
}
hm = h_alloc(H_Mem, (const char*)raw_p, flags | RES_KEY);
hm = h_alloc(H_Mem, (const char*)p, flags | RES_KEY);
if(!hm)
return 0;
set_alloc(raw_p, hm);
set_alloc(p, hm);
H_DEREF(hm, Mem, m);
m->p = p;
m->size = size;
m->raw_p = raw_p;
m->raw_size = raw_size;
m->user_p = raw_p;
m->user_size = raw_size;
m->dtor = dtor;
m->ctx = ctx;
@ -282,26 +280,18 @@ int mem_assign_user(Handle hm, void* user_p, size_t user_size)
{
H_DEREF(hm, Mem, m);
// make sure it's not already been assigned
// (doesn't make sense, probably logic error)
if(m->user_p != m->raw_p || m->user_size != m->raw_size)
{
debug_warn("mem_assign_user: already user_assign-ed");
return -1;
}
// security check: must be a subset of the existing buffer
// (otherwise, could reference other buffers / cause mischief)
char* raw_end = (char*)m->raw_p + m->raw_size;
char* user_end = (char*)m->user_p + m->user_size;
if(user_p < m->raw_p || user_end > raw_end)
char* end = (char*)m->p + m->size;
char* user_end = (char*)user_p + user_size;
if(user_p < m->p || user_end > end)
{
debug_warn("mem_assign_user: user buffer not contained in real buffer");
return -EINVAL;
}
m->user_p = user_p;
m->user_size = user_size;
m->p = user_p;
m->size = user_size;
return 0;
}
@ -324,9 +314,10 @@ void* mem_alloc(size_t size, const size_t align, uint flags, Handle* phm)
flags = res_cur_scope;
// otherwise, assume global scope
size_t raw_size = (size_t)round_up(size, align);
void* raw_p;
const size_t raw_size = size + align-1;
uintptr_t ctx;
MEM_DTOR dtor;
@ -343,11 +334,13 @@ void* mem_alloc(size_t size, const size_t align, uint flags, Handle* phm)
if(!raw_p)
return 0;
void* p = (void*)round_up((uintptr_t)raw_p, align);
Handle hm = mem_assign(raw_p, raw_size, flags, dtor, ctx);
Handle hm = mem_assign(p, size, flags, raw_p, raw_size, dtor, ctx);
if(!hm) // failed to allocate a handle
{
dtor(raw_p, raw_size, ctx);
dtor(p, size, ctx);
return 0;
}
@ -361,9 +354,9 @@ void* mem_alloc(size_t size, const size_t align, uint flags, Handle* phm)
*phm = hm;
if(flags & MEM_ZERO)
memset(raw_p, 0, raw_size);
memset(p, 0, size);
return raw_p;
return p;
}
@ -377,11 +370,11 @@ void* mem_get_ptr(Handle hm, size_t* user_size /* = 0 */)
return 0;
}
assert((!m->user_p || m->user_size) && "mem_get_ptr: mem corrupted (p valid =/=> size > 0)");
assert((!m->p || m->size) && "mem_get_ptr: mem corrupted (p valid =/=> size > 0)");
if(user_size)
*user_size = m->user_size;
return m->user_p;
*user_size = m->size;
return m->p;
}
@ -389,5 +382,5 @@ ssize_t mem_size(void* p)
{
Handle hm = find_alloc(p);
H_DEREF(hm, Mem, m);
return (ssize_t)m->user_size;
return (ssize_t)m->size;
}

View File

@ -29,7 +29,7 @@ extern int mem_free_h(Handle& hm);
// create a H_MEM handle of type MEM_USER,
// and assign it the specified memory range.
// dtor is called when the handle is freed, if non-NULL.
extern Handle mem_assign(void* p, size_t size, uint flags = 0, MEM_DTOR dtor = 0, uintptr_t ctx = 0);
extern Handle mem_assign(void* p, size_t size, uint flags = 0, void* raw_p = 0, size_t raw_size = 0, MEM_DTOR dtor = 0, uintptr_t ctx = 0);
extern int mem_assign_user(Handle hm, void* user_p, size_t user_size);