data-stack.c revision fd9972c1a2a630f3800ba4c73dd16cf03628cd50
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/*
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen data-stack.c : Data stack implementation
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen Copyright (c) 2001-2002 Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen Permission is hereby granted, free of charge, to any person obtaining
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen a copy of this software and associated documentation files (the
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "Software"), to deal in the Software without restriction, including
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen without limitation the rights to use, copy, modify, merge, publish,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen permit persons to whom the Software is furnished to do so, subject to
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen the following conditions:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen The above copyright notice and this permission notice shall be
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen included in all copies or substantial portions of the Software.
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen*/
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen/* @UNSAFE: whole file */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen#include "lib.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "data-stack.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include <stdlib.h>
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen/* Use malloc() and free() for all memory allocations. Useful for debugging
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen memory corruption. */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen/* #define DISABLE_DATA_STACK */
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#ifndef DISABLE_DATA_STACK
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen/* Initial stack size - this should be kept in a size that doesn't exceed
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen in a normal use to avoid extra malloc()ing. */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#ifdef DEBUG
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen# define INITIAL_STACK_SIZE (1024*10)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen#else
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen# define INITIAL_STACK_SIZE (1024*32)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#endif
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct stack_block {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct stack_block *next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen size_t size, left;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* unsigned char data[]; */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen#define SIZEOF_MEMBLOCK MEM_ALIGN(sizeof(struct stack_block))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#define STACK_BLOCK_DATA(block) \
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ((char *) (block) + SIZEOF_MEMBLOCK)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen/* current_frame_block contains last t_push()ed frames. After that new
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen stack_frame_block is created and it's ->prev is set to
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen current_frame_block. */
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen#define BLOCK_FRAME_COUNT 32
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainenstruct stack_frame_block {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct stack_frame_block *prev;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen struct stack_block *block[BLOCK_FRAME_COUNT];
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen size_t block_space_used[BLOCK_FRAME_COUNT];
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen size_t last_alloc_size[BLOCK_FRAME_COUNT];
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenunsigned int data_stack_frame = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int frame_pos = BLOCK_FRAME_COUNT-1; /* in current_frame_block */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct stack_frame_block *current_frame_block;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainenstatic struct stack_frame_block *unused_frame_blocks;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct stack_block *current_block; /* block now used for allocation */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct stack_block *unused_block; /* largest unused block is kept here */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainenstatic struct stack_block *last_buffer_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic size_t last_buffer_size;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainenunsigned int t_push(void)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen{
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen struct stack_frame_block *frame_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_pos++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (frame_pos == BLOCK_FRAME_COUNT) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* frame block full */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (data_stack_frame == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* kludgy, but allow this before initialization */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_pos = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen data_stack_init();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return t_push();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_pos = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (unused_frame_blocks == NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* allocate new block */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_block = calloc(sizeof(*frame_block), 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (frame_block == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_push(): Out of memory");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* use existing unused frame_block */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_block = unused_frame_blocks;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unused_frame_blocks = unused_frame_blocks->prev;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen frame_block->prev = current_frame_block;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen current_frame_block = frame_block;
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen }
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen /* mark our current position */
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen current_frame_block->block[frame_pos] = current_block;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen current_frame_block->block_space_used[frame_pos] = current_block->left;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen current_frame_block->last_alloc_size[frame_pos] = 0;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return data_stack_frame++;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void free_blocks(struct stack_block *block)
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen{
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen struct stack_block *next;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* free all the blocks, except if any of them is bigger than
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unused_block, replace it */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (block != NULL) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen next = block->next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (unused_block == NULL || block->size > unused_block->size) {
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen free(unused_block);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen unused_block = block;
a5e89374cb2fb2cad575fee6c3b33a9487ab9b3aTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen free(block);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen block = next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenunsigned int t_pop(void)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct stack_frame_block *frame_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int popped_frame_pos;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (frame_pos < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_pop() called with empty stack");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* update the current block */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen current_block = current_frame_block->block[frame_pos];
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->left = current_frame_block->block_space_used[frame_pos];
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#ifdef DEBUG
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen memset(STACK_BLOCK_DATA(current_block) +
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (current_block->size - current_block->left), 0xde,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->left);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#endif
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (current_block->next != NULL) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* free unused blocks */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen free_blocks(current_block->next);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->next = NULL;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen popped_frame_pos = frame_pos;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen if (frame_pos > 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_pos--;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* frame block is now unused, add it to unused list */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_pos = BLOCK_FRAME_COUNT-1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_block = current_frame_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_frame_block = frame_block->prev;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame_block->prev = unused_frame_blocks;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unused_frame_blocks = frame_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen return --data_stack_frame;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainenstatic struct stack_block *mem_block_alloc(size_t min_size)
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen{
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen struct stack_block *block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen size_t prev_size, alloc_size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen prev_size = current_block == NULL ? 0 : current_block->size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen alloc_size = nearest_power(prev_size + min_size);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen block = malloc(SIZEOF_MEMBLOCK + alloc_size);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (block == NULL) {
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen i_panic("mem_block_alloc(): "
437a8b0fe254057b0c1f1723d689bafa91cae2abTimo Sirainen "Out of memory when allocating %"PRIuSIZE_T" bytes",
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen alloc_size + SIZEOF_MEMBLOCK);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen }
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen block->size = alloc_size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen block->next = NULL;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return block;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic void *t_malloc_real(size_t size, int permanent)
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct stack_block *block;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen void *ret;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen#ifdef DEBUG
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int warn = FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#endif
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (size == 0 || size > SSIZE_T_MAX)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* reset t_buffer_get() mark - not really needed but makes it easier
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen to notice if t_malloc() is called between t_buffer_get() and
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen t_buffer_alloc() */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen last_buffer_block = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* allocate only aligned amount of memory so alignment comes
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen always properly */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen size = MEM_ALIGN(size);
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* used for t_try_realloc() */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_frame_block->last_alloc_size[frame_pos] = size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen if (current_block->left >= size) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* enough space in current block, use it */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = STACK_BLOCK_DATA(current_block) +
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (current_block->size - current_block->left);
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen if (permanent)
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen current_block->left -= size;
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* current block is full, see if we can use the unused_block */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (unused_block != NULL && unused_block->size >= size) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen block = unused_block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unused_block = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen block = mem_block_alloc(size);
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen#ifdef DEBUG
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen warn = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#endif
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen block->left = block->size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (permanent)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen block->left -= size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen block->next = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->next = block;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen current_block = block;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = STACK_BLOCK_DATA(current_block);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#ifdef DEBUG
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (warn) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* warn later, so that if i_warning() wants to allocate more
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen memory we don't go to infinite loop */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen i_warning("Growing data stack with: %"PRIuSIZE_T, block->size);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#endif
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid *t_malloc(size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return t_malloc_real(size, TRUE);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid *t_malloc0(size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen void *mem;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mem = t_malloc_real(size, TRUE);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen memset(mem, 0, size);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return mem;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainenint t_try_realloc(void *mem, size_t size)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen size_t last_alloc_size;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (size == 0 || size > SSIZE_T_MAX)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen last_alloc_size = current_frame_block->last_alloc_size[frame_pos];
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* see if we're trying to grow the memory we allocated last */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (STACK_BLOCK_DATA(current_block) +
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen (current_block->size - current_block->left -
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen last_alloc_size) == mem) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* yeah, see if we have space to grow */
fd14806f879f6cd4f023750e0c4cac27a7f94fbbTimo Sirainen size = MEM_ALIGN(size);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (current_block->left >= size - last_alloc_size) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* just shrink the available size */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->left -= size - last_alloc_size;
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen current_frame_block->last_alloc_size[frame_pos] = size;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return TRUE;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return FALSE;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainenvoid *t_buffer_get(size_t size)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen void *ret;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen ret = t_malloc_real(size, FALSE);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen last_buffer_size = size;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen last_buffer_block = current_block;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return ret;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenvoid *t_buffer_reget(void *buffer, size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen size_t old_size;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen void *new_buffer;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen old_size = last_buffer_size;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (size <= old_size)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen return buffer;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen new_buffer = t_buffer_get(size);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen if (new_buffer != buffer)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen memcpy(new_buffer, buffer, old_size);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return new_buffer;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenvoid t_buffer_alloc(size_t size)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen i_assert(last_buffer_block != NULL);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen i_assert(last_buffer_size >= size);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen i_assert(current_block->left >= size);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* we've already reserved the space, now we just mark it used */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen t_malloc_real(size, TRUE);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenvoid data_stack_init(void)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (data_stack_frame == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen data_stack_frame = 1;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen current_block = mem_block_alloc(INITIAL_STACK_SIZE);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->left = current_block->size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_block->next = NULL;
a7061727e8f1378228f110b23d816329d39ce82bTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen current_frame_block = NULL;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen unused_frame_blocks = NULL;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen frame_pos = BLOCK_FRAME_COUNT-1;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen last_buffer_block = NULL;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen last_buffer_size = 0;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen t_push();
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid data_stack_deinit(void)
a7061727e8f1378228f110b23d816329d39ce82bTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen t_pop();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (frame_pos != BLOCK_FRAME_COUNT-1)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("Missing t_pop() call");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (unused_frame_blocks != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct stack_frame_block *frame_block = unused_frame_blocks;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unused_frame_blocks = unused_frame_blocks->prev;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen free(frame_block);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen free(current_block);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen free(unused_block);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#else
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstruct stack_frame {
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct stack_frame *next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct frame_alloc *allocs;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen};
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainenstruct frame_alloc {
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen struct frame_alloc *next;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen void *mem;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenunsigned int data_stack_frame;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct stack_frame *current_frame;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic void *buffer_mem;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenunsigned int t_push(void)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct stack_frame *frame;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen frame = malloc(sizeof(struct stack_frame));
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (frame == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_push(): Out of memory");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame->allocs = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame->next = current_frame;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_frame = frame;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return data_stack_frame++;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenunsigned int t_pop(void)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct stack_frame *frame;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct frame_alloc *alloc;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen frame = current_frame;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen current_frame = frame->next;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen while (frame->allocs != NULL) {
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen alloc = frame->allocs;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen frame->allocs = alloc->next;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen free(alloc->mem);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen free(alloc);
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen }
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen free(frame);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return --data_stack_frame;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenstatic void add_alloc(void *mem)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct frame_alloc *alloc;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen alloc = malloc(sizeof(struct frame_alloc));
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen if (alloc == NULL)
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen i_panic("add_alloc(): Out of memory");
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen alloc->mem = mem;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen alloc->next = current_frame->allocs;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen current_frame->allocs = alloc;
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen if (buffer_mem != NULL) {
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen free(buffer_mem);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen buffer_mem = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid *t_malloc(size_t size)
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen void *mem;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen mem = malloc(size);
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen if (mem == NULL)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen i_panic("t_malloc(): Out of memory");
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen add_alloc(mem);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return mem;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainenvoid *t_malloc0(size_t size)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen void *mem;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mem = calloc(size, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mem == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_malloc0(): Out of memory");
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen add_alloc(mem);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return mem;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen}
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainenint t_try_realloc(void *mem __attr_unused__, size_t size __attr_unused__)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return FALSE;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen}
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainenvoid *t_buffer_get(size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen buffer_mem = realloc(buffer_mem, size);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (buffer_mem == NULL)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_panic("t_buffer_get(): Out of memory");
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return buffer_mem;
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid *t_buffer_reget(void *buffer, size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(buffer == buffer_mem);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen buffer_mem = realloc(buffer_mem, size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (buffer_mem == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_buffer_reget(): Out of memory");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return buffer_mem;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid t_buffer_alloc(size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen void *mem;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(buffer_mem != NULL);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mem = realloc(buffer_mem, size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mem == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("t_buffer_alloc(): Out of memory");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen buffer_mem = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen add_alloc(mem);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid data_stack_init(void)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen data_stack_frame = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen current_frame = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen buffer_mem = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen t_push();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid data_stack_deinit(void)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen t_pop();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (data_stack_frame != 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_panic("Missing t_pop() call");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#endif
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen