Interface to a stack which supports objects of differing size.
BinaryStack | Interface to a stack which supports objects of differing size. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file BinaryStack. |
C-kern/ | Implementation file BinaryStack impl. |
Types | |
struct binarystack_t | Export binarystack_t into global namespace. |
Functions | |
test | |
unittest_ds_inmem_binarystack | Test binarystack_t functionality. |
binarystack_t | Stores binary data in LIFO order. |
freeblocksize | The number of free bytes of memory block blockstart points to. |
blocksize | Size in bytes of allocated memory block blockstart points to. |
blockstart | Start address of latest allocated memory block. |
lifetime | |
binarystack_FREE | Static initializer. |
init_binarystack | Initializes stack object and reserves at least preallocate_size bytes. |
free_binarystack | Frees memory resources held by stack. |
query | |
isempty_binarystack | Returns true if stack contains no more data. |
size_binarystack | Returns the size of all pushed objects. |
top_binarystack | Returns the start address in memory of the last pushed object. |
change | |
pop_binarystack | Removes the last pushed object from the stack. |
push_binarystack | Allocates memory for new object and returns pointer to its start address. |
pop2_binarystack | Same functionality as pop_binarystack. |
push2_binarystack | Does same as push_binarystack but allocates a new block if necessary. |
inline implementation | |
Macros | |
isempty_binarystack | Implements binarystack_t.isempty_binarystack. |
pop_binarystack | Implements binarystack_t.pop_binarystack. |
push_binarystack | Implements binarystack_t.push_binarystack. |
top_binarystack | Implements binarystack_t.top_binarystack. |
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
© 2012 Jörg Seebohn
Header file BinaryStack.
Implementation file BinaryStack impl.
typedef struct binarystack_t binarystack_t
Export binarystack_t into global namespace.
test | |
unittest_ds_inmem_binarystack | Test binarystack_t functionality. |
int unittest_ds_inmem_binarystack( void )
Test binarystack_t functionality.
struct binarystack_t
Stores binary data in LIFO order.
This implementation tries to avoid any additional memory copy operations. Therefore the caller gets a pointer to the last pushed object as result. This pointer is considered valid as long the object is not popped off the stack.
Therefore calling additonal push_binarystack and corresponding pop_binarystack keeps this pointer valid. Calling free_binarystack does invalidate the pointer.
Push | You can push size bytes to the top of stack. This operation only allocates memory and returns a pointer to it. You need to initialize the content of the pushed object after it has been pushed. |
Pop | Removes size bytes from top of stack. To access the new top of stack (start address of a previously pushed object) call top_binarystack. |
If you push an object of size X the address of the next pushed object is aligned to size X. So if you need to align memory to number X make sure that every push operation pushes only objects with sizes which are multiples of X. The first pushed object is page aligned (see pagesize_vm).
freeblocksize | The number of free bytes of memory block blockstart points to. |
blocksize | Size in bytes of allocated memory block blockstart points to. |
blockstart | Start address of latest allocated memory block. |
lifetime | |
binarystack_FREE | Static initializer. |
init_binarystack | Initializes stack object and reserves at least preallocate_size bytes. |
free_binarystack | Frees memory resources held by stack. |
query | |
isempty_binarystack | Returns true if stack contains no more data. |
size_binarystack | Returns the size of all pushed objects. |
top_binarystack | Returns the start address in memory of the last pushed object. |
change | |
pop_binarystack | Removes the last pushed object from the stack. |
push_binarystack | Allocates memory for new object and returns pointer to its start address. |
pop2_binarystack | Same functionality as pop_binarystack. |
push2_binarystack | Does same as push_binarystack but allocates a new block if necessary. |
uint32_t freeblocksize
The number of free bytes of memory block blockstart points to.
uint32_t blocksize
Size in bytes of allocated memory block blockstart points to.
uint8_t * blockstart
Start address of latest allocated memory block. The size of this block is stored in blocksize.
void * top_binarystack( binarystack_t * stack )
Returns the start address in memory of the last pushed object. The returned address is the lowest address of the allocated memory space.
The returned pointer is never NULL. Even if the stack is empty. So always check with isempty_binarystack if there is an element on the stack.
Use <at_binarystack> the get the address of an object who is not top on stack.
int pop_binarystack( binarystack_t * stack, size_t size )
Removes the last pushed object from the stack. The parameter size must be set to the size of the last pushed object to remove it from the stack. If it is set to the sum of x last pushed objects then these x objects are removed from the stack at once. Call top_binarystack to get the new address of the object on top of the stack.
Popping only part of the last pushed object shrinks the memory of it. Use top_binarystack to get the new address of a partially shrinked object. If size is bigger than size_binarystack the the error EINVAL is returned and nothing is done. This function calls pop2_binarystack if one or more memory blocks have to be freed.
int push_binarystack( binarystack_t * stack, /*out*/void ** lastpushed )
Allocates memory for new object and returns pointer to its start address. The returned address is the lowest address of the allocated memory space. This function is implemented as generic macro and the size of the newly pushed object is calculated as
size = sizeof(**lastpushed) ;
If not enough preallocated memory is available a call to push2_binarystack is made which allocates a new block of memory. In case of an error ENOMEM is returned.
The memory is managed as a list of allocated blocks so the address of already pushed objects never change.
stack | binary stack object. |
lastpushed | A pointer to pointer of a concrete type whose newly allocated address is returned. The allocated memory space contains random data. The size of the object is determined from its type (see above). |
int pop2_binarystack( binarystack_t * stack, size_t size )
Same functionality as pop_binarystack. This function is called from pop_binarystack in case one or more memory blocks must be freed.
If the memory subsystem returns an error this function returns this error. But it continues the work until size bytes are popped off the stack. The reason is that the error can occur any time after some blocks have already been freed. So doing nothing in case of an error does not work here.
int push2_binarystack( binarystack_t * stack, uint32_t size, /*out*/uint8_t ** lastpushed )
Does same as push_binarystack but allocates a new block if necessary. This function is called from push_binarystack in case a new memory must be allocated. Do not call this function - always use push_binarystack.
Macros | |
isempty_binarystack | Implements binarystack_t.isempty_binarystack. |
pop_binarystack | Implements binarystack_t.pop_binarystack. |
push_binarystack | Implements binarystack_t.push_binarystack. |
top_binarystack | Implements binarystack_t.top_binarystack. |
#define isempty_binarystack( stack ) ((stack)->freeblocksize == (stack)->blocksize)
Implements binarystack_t.isempty_binarystack.
#define pop_binarystack( stack, size ) ( __extension__ ({ int _err ; binarystack_t * _stack = (stack) ; uint32_t _size = (size) ; if (_stack->blocksize - _stack->freeblocksize > _size) { _stack->freeblocksize += _size ; _err = 0 ; } else { _err = pop2_binarystack(_stack, _size) ; } _err ; }))
Implements binarystack_t.pop_binarystack.
Implements binarystack_t.push_binarystack.
#define top_binarystack( stack ) ((void*)(&(stack)->blockstart[(stack)->freeblocksize]))
Implements binarystack_t.top_binarystack.
Export binarystack_t into global namespace.
typedef struct binarystack_t binarystack_t
Stores binary data in LIFO order.
struct binarystack_t
Test binarystack_t functionality.
int unittest_ds_inmem_binarystack( void )
The number of free bytes of memory block blockstart points to.
uint32_t freeblocksize
Start address of latest allocated memory block.
uint8_t * blockstart
Size in bytes of allocated memory block blockstart points to.
uint32_t blocksize
Static initializer.
#define binarystack_FREE { 0, 0, 0 }
Initializes stack object and reserves at least preallocate_size bytes.
int init_binarystack( /*out*/binarystack_t * stack, uint32_t preallocate_size )
Frees memory resources held by stack.
int free_binarystack( binarystack_t * stack )
Returns true if stack contains no more data.
int isempty_binarystack( const binarystack_t * stack )
Returns the size of all pushed objects.
size_t size_binarystack( binarystack_t * stack )
Returns the start address in memory of the last pushed object.
void * top_binarystack( binarystack_t * stack )
Removes the last pushed object from the stack.
int pop_binarystack( binarystack_t * stack, size_t size )
Allocates memory for new object and returns pointer to its start address.
int push_binarystack( binarystack_t * stack, /*out*/void ** lastpushed )
Same functionality as pop_binarystack.
int pop2_binarystack( binarystack_t * stack, size_t size )
Does same as push_binarystack but allocates a new block if necessary.
int push2_binarystack( binarystack_t * stack, uint32_t size, /*out*/uint8_t ** lastpushed )
Implements binarystack_t.isempty_binarystack.
#define isempty_binarystack( stack ) ((stack)->freeblocksize == (stack)->blocksize)
Implements binarystack_t.pop_binarystack.
#define pop_binarystack( stack, size ) ( __extension__ ({ int _err ; binarystack_t * _stack = (stack) ; uint32_t _size = (size) ; if (_stack->blocksize - _stack->freeblocksize > _size) { _stack->freeblocksize += _size ; _err = 0 ; } else { _err = pop2_binarystack(_stack, _size) ; } _err ; }))
Implements binarystack_t.top_binarystack.
#define top_binarystack( stack ) ((void*)(&(stack)->blockstart[(stack)->freeblocksize]))
Returns the virtual memory page size supported by the underlying system.
uint32_t pagesize_vm( void )