data-stack.c revision db562225ac6e1f0e2b1a87af97f115febb09cba9
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/*
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data-stack.c : Data stack implementation
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen Copyright (c) 2001-2002 Timo Sirainen
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Permission is hereby granted, free of charge, to any person obtaining
1dd875d96ab5640f78250079961c10e99ed4aa79Timo Sirainen a copy of this software and associated documentation files (the
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen "Software"), to deal in the Software without restriction, including
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen without limitation the rights to use, copy, modify, merge, publish,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainen permit persons to whom the Software is furnished to do so, subject to
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen the following conditions:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen The above copyright notice and this permission notice shall be
66ae183b6e895216037bd921367670f4b0665911Timo Sirainen included in all copies or substantial portions of the Software.
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen*/
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen#include "lib.h"
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#include "data-stack.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdlib.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Use malloc() and free() for all memory allocations. Useful for debugging
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memory corruption. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* #define DISABLE_DATA_STACK */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifndef DISABLE_DATA_STACK
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainen/* Max. number of bytes to even try to allocate. This is done just to avoid
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainen allocating less memory than was actually requested because of integer
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen overflows. */
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen#define MAX_ALLOC_SIZE SSIZE_T_MAX
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen/* Initial stack size - this should be kept in a size that doesn't exceed
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen in a normal use to avoid extra malloc()ing. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifdef DEBUG
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# define INITIAL_STACK_SIZE (1024*10)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#else
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen# define INITIAL_STACK_SIZE (1024*32)
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen#endif
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainentypedef struct _StackBlock StackBlock;
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainentypedef struct _StackFrameBlock StackFrameBlock;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainenstruct _StackBlock {
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen StackBlock *next;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen size_t size, left;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* unsigned char data[]; */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen#define SIZEOF_MEMBLOCK MEM_ALIGN(sizeof(StackBlock))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen#define STACK_BLOCK_DATA(block) \
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen ((char *) (block) + SIZEOF_MEMBLOCK)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen/* current_frame_block contains last t_push()ed frames. After that new
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen StackFrameBlock is created and it's ->prev is set to current_frame_block. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#define BLOCK_FRAME_COUNT 32
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainenstruct _StackFrameBlock {
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen StackFrameBlock *prev;
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen StackBlock *block[BLOCK_FRAME_COUNT];
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen size_t block_space_used[BLOCK_FRAME_COUNT];
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen size_t last_alloc_size[BLOCK_FRAME_COUNT];
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen};
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenunsigned int data_stack_frame;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int frame_pos; /* current frame position current_frame_block */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic StackFrameBlock *current_frame_block; /* current stack frame block */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic StackFrameBlock *unused_frame_blocks; /* unused stack frames */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
80fc743146da5130de34174cdaad2576f103723fTimo Sirainenstatic StackBlock *current_block; /* block currently used for allocation */
80fc743146da5130de34174cdaad2576f103723fTimo Sirainenstatic StackBlock *unused_block; /* largest unused block is kept here */
80fc743146da5130de34174cdaad2576f103723fTimo Sirainen
80fc743146da5130de34174cdaad2576f103723fTimo Sirainenstatic StackBlock *last_buffer_block;
80fc743146da5130de34174cdaad2576f103723fTimo Sirainenstatic size_t last_buffer_size;
80fc743146da5130de34174cdaad2576f103723fTimo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenunsigned int t_push(void)
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen{
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen StackFrameBlock *frame_block;
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen frame_pos++;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen if (frame_pos == BLOCK_FRAME_COUNT) {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen /* frame block full */
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen frame_pos = 0;
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen if (unused_frame_blocks == NULL) {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* allocate new block */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen frame_block = calloc(sizeof(StackFrameBlock), 1);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (frame_block == NULL)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_panic("t_push(): Out of memory");
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen } else {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* use existing unused frame_block */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen frame_block = unused_frame_blocks;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen unused_frame_blocks = unused_frame_blocks->prev;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen frame_block->prev = current_frame_block;
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen current_frame_block = frame_block;
1e923fcf497665fe071a154c31fb452766b0b2deTimo Sirainen }
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen
1e923fcf497665fe071a154c31fb452766b0b2deTimo Sirainen /* mark our current position */
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen current_frame_block->block[frame_pos] = current_block;
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen current_frame_block->block_space_used[frame_pos] = current_block->left;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen current_frame_block->last_alloc_size[frame_pos] = 0;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen return data_stack_frame++;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen}
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainenstatic void free_blocks(StackBlock *block)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen{
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen /* free all the blocks, except if any of them is bigger than
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen unused_block, replace it */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen while (block != NULL) {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen if (unused_block == NULL || block->size > unused_block->size) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen free(unused_block);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen unused_block = block;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen } else {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen free(block);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen }
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen block = block->next;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen }
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen}
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainenunsigned int t_pop(void)
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen{
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen StackFrameBlock *frame_block;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen int popped_frame_pos;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen if (frame_pos < 0)
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen i_panic("t_pop() called with empty stack");
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen /* update the current block */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen current_block = current_frame_block->block[frame_pos];
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen current_block->left = current_frame_block->block_space_used[frame_pos];
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#ifdef DEBUG
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen memset(STACK_BLOCK_DATA(current_block) +
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen (current_block->size - current_block->left), 0xde,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen current_block->left);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#endif
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen if (current_block->next != NULL) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* free unused blocks */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen free_blocks(current_block->next);
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen current_block->next = NULL;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen popped_frame_pos = frame_pos;
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen if (frame_pos > 0)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen frame_pos--;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen else {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* frame block is now unused, add it to unused list */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen frame_pos = BLOCK_FRAME_COUNT-1;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen frame_block = current_frame_block;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen current_frame_block = frame_block->prev;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen frame_block->prev = unused_frame_blocks;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen unused_frame_blocks = frame_block;
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return --data_stack_frame;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainenstatic StackBlock *mem_block_alloc(size_t min_size)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen StackBlock *block;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen size_t prev_size, alloc_size;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen prev_size = current_block == NULL ? 0 : current_block->size;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen alloc_size = nearest_power(prev_size + min_size);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen block = malloc(SIZEOF_MEMBLOCK + alloc_size);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (block == NULL) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_panic("mem_block_alloc(): "
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen "Out of memory when allocating %"PRIuSIZE_T" bytes",
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen alloc_size + SIZEOF_MEMBLOCK);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen block->size = alloc_size;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen block->next = NULL;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen return block;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenstatic void *t_malloc_real(size_t size, int permanent)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen{
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen StackBlock *block;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen void *ret;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen if (size == 0)
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen return NULL;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen if (size > MAX_ALLOC_SIZE)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen i_panic("Trying to allocate too much memory");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* reset t_buffer_get() mark - not really needed but makes it easier
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen to notice if t_malloc() is called between t_buffer_get() and
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen t_buffer_alloc() */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen last_buffer_block = NULL;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* allocate only aligned amount of memory so alignment comes
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen always properly */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen size = MEM_ALIGN(size);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* used for t_try_realloc() */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen current_frame_block->last_alloc_size[frame_pos] = size;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (current_block->left >= size) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen /* enough space in current block, use it */
6825360d446542046757b06064282301c4c6b27cTimo Sirainen ret = STACK_BLOCK_DATA(current_block) +
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen (current_block->size - current_block->left);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (permanent)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen current_block->left -= size;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen return ret;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen }
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen /* current block is full, see if we can use the unused_block */
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen if (unused_block != NULL && unused_block->size >= size) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen block = unused_block;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unused_block = NULL;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen } else {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen block = mem_block_alloc(size);
6825360d446542046757b06064282301c4c6b27cTimo Sirainen#ifdef DEBUG
6825360d446542046757b06064282301c4c6b27cTimo Sirainen i_warning("Growing data stack with: %"PRIuSIZE_T, block->size);
6825360d446542046757b06064282301c4c6b27cTimo Sirainen#endif
6825360d446542046757b06064282301c4c6b27cTimo Sirainen }
6825360d446542046757b06064282301c4c6b27cTimo Sirainen
6825360d446542046757b06064282301c4c6b27cTimo Sirainen block->left = block->size;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen if (permanent)
6825360d446542046757b06064282301c4c6b27cTimo Sirainen block->left -= size;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen block->next = NULL;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen
c8d093d149253fe8faec267c5057f45fe626f84cTimo Sirainen current_block->next = block;
c8d093d149253fe8faec267c5057f45fe626f84cTimo Sirainen current_block = block;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen
6825360d446542046757b06064282301c4c6b27cTimo Sirainen return STACK_BLOCK_DATA(current_block);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid *t_malloc(size_t size)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen return t_malloc_real(size, TRUE);
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid *t_malloc0(size_t size)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen void *mem;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mem = t_malloc_real(size, TRUE);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen memset(mem, 0, size);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return mem;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint t_try_realloc(void *mem, size_t size)
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen{
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen size_t last_alloc_size;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen last_alloc_size = current_frame_block->last_alloc_size[frame_pos];
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen /* see if we're trying to grow the memory we allocated last */
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen if (STACK_BLOCK_DATA(current_block) +
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen (current_block->size - current_block->left -
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen last_alloc_size) == mem) {
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen /* yeah, see if we have space to grow */
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen size = MEM_ALIGN(size);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen if (current_block->left >= size - last_alloc_size) {
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen /* just shrink the available size */
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen current_block->left -= size - last_alloc_size;
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen current_frame_block->last_alloc_size[frame_pos] = size;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return TRUE;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return FALSE;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainenvoid *t_buffer_get(size_t size)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen{
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen void *ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ret = t_malloc_real(size, FALSE);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen last_buffer_size = size;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen last_buffer_block = current_block;
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen return ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainenvoid *t_buffer_reget(void *buffer, size_t size)
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen{
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen size_t old_size;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen void *new_buffer;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen old_size = last_buffer_size;
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen if (size <= old_size)
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen return buffer;
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen new_buffer = t_buffer_get(size);
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen if (new_buffer != buffer)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen memcpy(new_buffer, buffer, old_size);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return new_buffer;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid t_buffer_alloc(size_t size)
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(last_buffer_block != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(last_buffer_size >= size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(current_block->left >= size);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen /* we've already reserved the space, now we just mark it used */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen t_malloc_real(size, TRUE);
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainenvoid data_stack_init(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data_stack_frame = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen current_block = mem_block_alloc(INITIAL_STACK_SIZE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen current_block->left = current_block->size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen current_block->next = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen current_frame_block = NULL;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen unused_frame_blocks = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen frame_pos = BLOCK_FRAME_COUNT-1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen t_push();
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen last_buffer_block = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen last_buffer_size = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainenvoid data_stack_deinit(void)
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen{
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen t_pop();
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen if (frame_pos != BLOCK_FRAME_COUNT-1)
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen i_panic("Missing t_pop() call");
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen while (unused_frame_blocks != NULL) {
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen StackFrameBlock *frame_block = unused_frame_blocks;
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen unused_frame_blocks = unused_frame_blocks->prev;
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen free(frame_block);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen }
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen free(current_block);
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen free(unused_block);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#else
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainentypedef struct _StackFrame StackFrame;
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainentypedef struct _FrameAlloc FrameAlloc;
0b49cfeae91a4020a404714b11c99e8e955fb631Timo Sirainen
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainenstruct _StackFrame {
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen StackFrame *next;
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen FrameAlloc *allocs;
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen};
0b49cfeae91a4020a404714b11c99e8e955fb631Timo Sirainen
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainenstruct _FrameAlloc {
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen FrameAlloc *next;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen void *mem;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen};
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic StackFrame *current_frame;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainenstatic void *buffer_mem;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenunsigned int t_push(void)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen{
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen StackFrame *frame;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen frame = malloc(sizeof(StackFrame));
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (frame == NULL)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen i_panic("t_push(): Out of memory");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen frame->allocs = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen frame->next = current_frame;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen current_frame = frame;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return data_stack_frame++;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainenunsigned int t_pop(void)
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen{
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen StackFrame *frame;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen FrameAlloc *alloc;
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen frame = current_frame;
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen current_frame = frame->next;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
99e8698f598d2b83da7c581584a538c0713fd11dTimo Sirainen while (frame->allocs != NULL) {
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen alloc = frame->allocs;
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen frame->allocs = alloc->next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen free(alloc->mem);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen free(alloc);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen }
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen free(frame);
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return --data_stack_frame;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen}
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void add_alloc(void *mem)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen{
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen FrameAlloc *alloc;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen alloc = malloc(sizeof(FrameAlloc));
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen if (alloc == NULL)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen i_panic("add_alloc(): Out of memory");
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen alloc->mem = mem;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen alloc->next = current_frame->allocs;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen current_frame->allocs = alloc;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen if (buffer_mem != NULL) {
589a9c6e8ee22071c14171c04bfc6bfe17121871Timo Sirainen free(buffer_mem);
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen buffer_mem = NULL;
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen }
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen}
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainenvoid *t_malloc(size_t size)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen{
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen void *mem;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen mem = malloc(size);
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen if (mem == NULL)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen i_panic("t_malloc(): Out of memory");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen add_alloc(mem);
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return mem;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainenvoid *t_malloc0(size_t size)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen{
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen void *mem;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mem = calloc(size, 1);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen if (mem == NULL)
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen i_panic("t_malloc0(): Out of memory");
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen add_alloc(mem);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen return mem;
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen}
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainenint t_try_realloc(void *mem, size_t size)
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen{
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen void *new_mem;
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen new_mem = realloc(mem, size);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen if (new_mem == mem)
c2feb7d13482d0f60691cd71d06d42a80df99397Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen free(new_mem);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen return FALSE;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid *t_buffer_get(size_t size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_mem = realloc(buffer_mem, size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (buffer_mem == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_panic("t_buffer_get(): Out of memory");
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen return buffer_mem;
e670e1783fe4541dc3fc6109a181d45b0a9c2635Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e670e1783fe4541dc3fc6109a181d45b0a9c2635Timo Sirainenvoid *t_buffer_reget(void *buffer, size_t size)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen i_assert(buffer == buffer_mem);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen buffer_mem = realloc(buffer_mem, size);
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen if (buffer_mem == NULL)
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen i_panic("t_buffer_reget(): Out of memory");
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen return buffer_mem;
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid t_buffer_alloc(size_t size)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen void *mem;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen i_assert(buffer_mem != NULL);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mem = realloc(buffer_mem, size);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen if (mem == NULL)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen i_panic("t_buffer_alloc(): Out of memory");
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen buffer_mem = NULL;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen add_alloc(mem);
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen}
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainenvoid data_stack_init(void)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen{
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen data_stack_frame = 0;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen current_frame = NULL;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen buffer_mem = NULL;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen t_push();
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen}
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainenvoid data_stack_deinit(void)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen{
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen t_pop();
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (data_stack_frame != 0)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen i_panic("Missing t_pop() call");
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen}
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen#endif
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen