-
Notifications
You must be signed in to change notification settings - Fork 813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aligned memory allocaion #4277
base: master
Are you sure you want to change the base?
aligned memory allocaion #4277
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,8 @@ | |
|
||
#include <pj/string.h> | ||
|
||
#define ALIGN_PTR(PTR,ALIGNMENT) (PTR + (-(pj_ssize_t)(PTR) & (ALIGNMENT-1))) | ||
|
||
|
||
PJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool ) | ||
{ | ||
|
@@ -37,28 +39,38 @@ PJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool ) | |
return used_size; | ||
} | ||
|
||
PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_block *block, pj_size_t size ) | ||
PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_block *block, pj_size_t alignment, | ||
pj_size_t size ) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to check (
Also in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NB! c++ new() returns uniqiue address for each allocation (even for size==0). This may be better than pjsip's behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO the existing spec is okay, it can be used for example to check the pointer belongs to some buffer. |
||
/* The operation below is valid for size==0. | ||
* When size==0, the function will return the pointer to the pool | ||
* memory address, but no memory will be allocated. | ||
*/ | ||
if (size & (PJ_POOL_ALIGNMENT-1)) { | ||
size = (size + PJ_POOL_ALIGNMENT) & ~(PJ_POOL_ALIGNMENT-1); | ||
if (size & (alignment -1)) { | ||
size = (size + alignment) & ~(alignment -1); | ||
} | ||
if ((pj_size_t)(block->end - block->cur) >= size) { | ||
void *ptr = block->cur; | ||
block->cur += size; | ||
unsigned char *ptr = ALIGN_PTR(block->cur, alignment); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pls move |
||
if (ptr < block->end && (pj_size_t)(block->end - ptr) >= size) { | ||
block->cur = ptr + size; | ||
return ptr; | ||
} | ||
return NULL; | ||
} | ||
|
||
PJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size) | ||
{ | ||
void *ptr = pj_pool_alloc_from_block(pool->block_list.next, size); | ||
return pj_pool_aligned_alloc(pool, 0, size); | ||
} | ||
|
||
PJ_IDECL(void *) pj_pool_aligned_alloc(pj_pool_t *pool, pj_size_t alignment, | ||
pj_size_t size) | ||
{ | ||
if (alignment < pool->alignment) | ||
alignment = pool->alignment; | ||
void *ptr = pj_pool_alloc_from_block(pool->block_list.next, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pls move |
||
alignment, size); | ||
if (!ptr) | ||
ptr = pj_pool_allocate_find(pool, size); | ||
ptr = pj_pool_allocate_find(pool, alignment, size); | ||
return ptr; | ||
} | ||
|
||
|
@@ -82,7 +94,17 @@ PJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f, | |
pj_size_t increment_size, | ||
pj_pool_callback *callback) | ||
{ | ||
return (*f->create_pool)(f, name, initial_size, increment_size, callback); | ||
return pj_pool_aligned_create(f, name, initial_size, increment_size, 0, callback); | ||
} | ||
|
||
PJ_IDECL(pj_pool_t *) pj_pool_aligned_create(pj_pool_factory *f, | ||
const char *name, | ||
pj_size_t initial_size, | ||
pj_size_t increment_size, | ||
size_t alignment, | ||
pj_pool_callback *callback) | ||
{ | ||
return (*f->create_pool)(f, name, initial_size, increment_size, alignment, callback); | ||
} | ||
|
||
PJ_IDEF(void) pj_pool_release( pj_pool_t *pool ) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ | |
#endif | ||
|
||
#define LOG(expr) PJ_LOG(6,expr) | ||
#define ALIGN_PTR(PTR,ALIGNMENT) (PTR + (-(pj_ssize_t)(PTR) & (ALIGNMENT-1))) | ||
|
||
PJ_DEF_DATA(int) PJ_NO_MEMORY_EXCEPTION; | ||
|
||
|
@@ -72,7 +71,7 @@ static pj_pool_block *pj_pool_create_block( pj_pool_t *pool, pj_size_t size) | |
block->end = ((unsigned char*)block) + size; | ||
|
||
/* Set the start pointer, aligning it as needed */ | ||
block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT); | ||
block->cur = ALIGN_PTR(block->buf, pool->alignment); | ||
|
||
/* Insert in the front of the list. */ | ||
pj_list_insert_after(&pool->block_list, block); | ||
|
@@ -90,7 +89,8 @@ static pj_pool_block *pj_pool_create_block( pj_pool_t *pool, pj_size_t size) | |
* a new block might be created (depending on whether the pool is allowed | ||
* to resize). | ||
*/ | ||
PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size) | ||
PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t alignment, | ||
pj_size_t size) | ||
{ | ||
pj_pool_block *block = pool->block_list.next; | ||
void *p; | ||
|
@@ -100,7 +100,7 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size) | |
PJ_CHECK_STACK(); | ||
|
||
while (block != &pool->block_list) { | ||
p = pj_pool_alloc_from_block(block, size); | ||
p = pj_pool_alloc_from_block(block, alignment, size); | ||
if (p != NULL) | ||
return p; | ||
|
||
|
@@ -131,11 +131,11 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size) | |
* the block. | ||
*/ | ||
if (pool->increment_size < | ||
size + sizeof(pj_pool_block) + PJ_POOL_ALIGNMENT) | ||
size + sizeof(pj_pool_block) + alignment) | ||
{ | ||
pj_size_t count; | ||
count = (size + pool->increment_size + sizeof(pj_pool_block) + | ||
PJ_POOL_ALIGNMENT) / | ||
alignment) / | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same bug as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like GH losts my long written comment... :( I can reproduce the bug with this code (it's producing assertion error in
If you don't mind you can add that to the pool's unit test |
||
pool->increment_size; | ||
block_size = count * pool->increment_size; | ||
|
||
|
@@ -153,7 +153,7 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size) | |
if (!block) | ||
return NULL; | ||
|
||
p = pj_pool_alloc_from_block(block, size); | ||
p = pj_pool_alloc_from_block(block, alignment, size); | ||
pj_assert(p != NULL); | ||
#if PJ_DEBUG | ||
if (p == NULL) { | ||
|
@@ -166,15 +166,18 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size) | |
/* | ||
* Internal function to initialize pool. | ||
*/ | ||
PJ_DEF(void) pj_pool_init_int( pj_pool_t *pool, | ||
const char *name, | ||
pj_size_t increment_size, | ||
pj_pool_callback *callback) | ||
PJ_DEF(void) pj_pool_init_int(pj_pool_t *pool, | ||
const char *name, | ||
pj_size_t increment_size, | ||
pj_size_t alignment, | ||
pj_pool_callback *callback) | ||
{ | ||
|
||
PJ_CHECK_STACK(); | ||
|
||
pool->increment_size = increment_size; | ||
pool->callback = callback; | ||
pool->alignment = (alignment < PJ_POOL_ALIGNMENT) ? PJ_POOL_ALIGNMENT : alignment; | ||
|
||
if (name) { | ||
char *p = pj_ansi_strchr(name, '%'); | ||
|
@@ -196,6 +199,7 @@ PJ_DEF(void) pj_pool_init_int( pj_pool_t *pool, | |
PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name, | ||
pj_size_t initial_size, | ||
pj_size_t increment_size, | ||
pj_size_t alignment, | ||
pj_pool_callback *callback) | ||
{ | ||
pj_pool_t *pool; | ||
|
@@ -208,6 +212,9 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name, | |
PJ_ASSERT_RETURN(initial_size >= sizeof(pj_pool_t)+sizeof(pj_pool_block), | ||
NULL); | ||
|
||
if (alignment < PJ_POOL_ALIGNMENT) | ||
alignment = PJ_POOL_ALIGNMENT; | ||
|
||
/* If callback is NULL, set calback from the policy */ | ||
if (callback == NULL) | ||
callback = f->policy.callback; | ||
|
@@ -230,11 +237,11 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name, | |
block->end = buffer + initial_size; | ||
|
||
/* Set the start pointer, aligning it as needed */ | ||
block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT); | ||
block->cur = ALIGN_PTR(block->buf, alignment); | ||
|
||
pj_list_insert_after(&pool->block_list, block); | ||
|
||
pj_pool_init_int(pool, name, increment_size, callback); | ||
pj_pool_init_int(pool, name, increment_size, alignment, callback); | ||
|
||
/* Pool initial capacity and used size */ | ||
pool->capacity = initial_size; | ||
|
@@ -275,7 +282,7 @@ static void reset_pool(pj_pool_t *pool) | |
block = pool->block_list.next; | ||
|
||
/* Set the start pointer, aligning it as needed */ | ||
block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT); | ||
block->cur = ALIGN_PTR(block->buf, pool->alignment); | ||
|
||
pool->capacity = block->end - (unsigned char*)pool; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to PJ_POOL_ALIGN_PTR, since this potentially be included as public API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1)))
this is from row.h libyuv
Shouldn't this be public too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The objective here is to prevent conflict from symbols that we (pjsip) declare with symbols from other software when the users include our header files mixed with header files from other software. That's why we put
pj
/PJ
prefix everywhere.SInce
pool_i.h
can potentially be included by user (i.e. whenPJ_FUNCTIONS_ARE_INLINED
is set to nonzero), all symbols declared here must be properly prefixed withpj
/PJ
.As for
IS_ALIGNED
inlibyuv/row.h
, since this is not our software (although it is included in our distribution), we can't control what naming they use, and we don't want to modify it, so it is what it is.