1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

alloc_on_stack: simplify the API

This commit is contained in:
Sergei Golubchik
2019-08-22 20:24:15 +02:00
parent 6c50875a38
commit 2e665fb294
14 changed files with 162 additions and 283 deletions

View File

@@ -18,10 +18,10 @@
#define _my_stack_alloc_h
/*
Do allocation trough alloca if there is enough stack available.
Do allocation through alloca if there is enough stack available.
If not, use my_malloc() instead.
The idea is that to be able to alloc as much as possible trough the
The idea is that to be able to alloc as much as possible through the
stack. To ensure this, we have two different limits, on for big
blocks and one for small blocks. This will enable us to continue to
do allocation for small blocks even when there is less stack space
@@ -42,47 +42,25 @@
/* Allocate small blocks as long as there is this much left */
#define STACK_ALLOC_SMALL_BLOCK 1024*32
struct st_stack_alloc
{
void **stack_ends_here; /* Set on init */
size_t stack_for_big_blocks;
size_t stack_for_small_blocks;
size_t small_block_size;
};
typedef struct st_stack_alloc STACK_ALLOC;
/* Allocate small blocks as long as there is this much left */
#define STACK_ALLOC_SMALL_BLOCK_SIZE 4096
/*
Initialize STACK_ALLOC structure
*/
static inline void init_stack_alloc(STACK_ALLOC *alloc,
size_t stack_for_big_blocks,
size_t stack_for_small_blocks,
size_t small_block_size)
{
alloc->stack_ends_here= &my_thread_var->stack_ends_here;
alloc->stack_for_big_blocks= stack_for_big_blocks;
alloc->stack_for_small_blocks= stack_for_small_blocks;
alloc->small_block_size= small_block_size;
}
/*
Allocate a block on stack or trough malloc.
Allocate a block on stack or through malloc.
The 'must_be_freed' variable will be set to 1 if malloc was called.
'must_be_freed' must be a variable on the stack!
*/
#ifdef HAVE_ALLOCA
#define alloc_on_stack(alloc, res, must_be_freed, size) \
#define alloc_on_stack(stack_end, res, must_be_freed, size) \
do \
{ \
size_t stack_left= available_stack_size(&(must_be_freed), \
*(alloc)->stack_ends_here); \
if (stack_left > (size_t) (size) && \
((alloc)->stack_for_big_blocks < stack_left - (size) || \
(((alloc)->stack_for_small_blocks < stack_left - (size)) && \
((alloc)->small_block_size <= (size_t) (size))))) \
size_t alloc_size= (size); \
size_t stack_left= available_stack_size(&alloc_size, (stack_end)); \
if (stack_left > alloc_size && \
(STACK_ALLOC_BIG_BLOCK < stack_left - alloc_size || \
((STACK_ALLOC_SMALL_BLOCK < stack_left - alloc_size) && \
(STACK_ALLOC_SMALL_BLOCK_SIZE <= alloc_size)))) \
{ \
(must_be_freed)= 0; \
(res)= alloca(size); \
@@ -92,13 +70,13 @@ static inline void init_stack_alloc(STACK_ALLOC *alloc,
(must_be_freed)= 1; \
(res)= my_malloc(size, MYF(MY_THREAD_SPECIFIC | MY_WME)); \
} \
}
} while(0)
#else
#define alloc_on_stack(alloc, res, must_be_freed, size) \
{ \
#define alloc_on_stack(stack_end, res, must_be_freed, size) \
do { \
(must_be_freed)= 1; \
(res)= my_malloc(size, MYF(MY_THREAD_SPECIFIC | MY_WME)); \
}
} while(0)
#endif /* HAVE_ALLOCA */