/* * SPDX-FileCopyrightText: 2006-2016 Matthew Conte * * SPDX-License-Identifier: BSD-3-Clause *//* ... */#pragmaonce#ifdefined(__cplusplus)extern"C"{#endif/*** Constants definition for poisoning.** These defines are used as 3rd argument of tlsf_poison_fill_region() for readability purposes.*//* ... */#definePOISONING_AFTER_FREEtrue#definePOISONING_AFTER_MALLOC!POISONING_AFTER_FREE/* A type used for casting when doing pointer arithmetic. */typedefptrdiff_ttlsfptr_t;/*** Cast and min/max macros.*//* ... */#if!defined(tlsf_cast)#definetlsf_cast(t,exp)((t)(exp))#endif#if!defined(tlsf_min)#definetlsf_min(a,b)((a)<(b)?(a):(b))#endif#if!defined(tlsf_max)#definetlsf_max(a,b)((a)>(b)?(a):(b))#endif/*** Set assert macro, if it has not been provided by the user.*//* ... */#if!defined(tlsf_assert)#definetlsf_assertassert#endiftypedefstructblock_header_t{/* Points to the previous physical block. */structblock_header_t*prev_phys_block;/* The size of this block, excluding the block header. */size_tsize;/* Next and previous free blocks. */structblock_header_t*next_free;structblock_header_t*prev_free;}{ ... }block_header_t;/* User data starts directly after the size field in a used block. */#defineblock_start_offset(offsetof(block_header_t,size)+sizeof(size_t))/*** A free block must be large enough to store its header minus the size of** the prev_phys_block field, and no larger than the number of addressable** bits for FL_INDEX.*//* ... */#defineblock_size_min(sizeof(block_header_t)-sizeof(block_header_t*))/*** Since block sizes are always at least a multiple of 4, the two least** significant bits of the size field are used to store the block status:** - bit 0: whether block is busy or free** - bit 1: whether previous block is busy or free*//* ... */#defineblock_header_free_bit(1UL<<0)#defineblock_header_prev_free_bit(1UL<<1)/*** The size of the block header exposed to used blocks is the size field.** The prev_phys_block field is stored *inside* the previous free block.*//* ... */#defineblock_header_overhead(sizeof(size_t))5 defines/*** block_header_t member functions.*//* ... */staticinline__attribute__((always_inline))size_tblock_size(constblock_header_t*block){returnblock->size&~(block_header_free_bit|block_header_prev_free_bit);}{ ... }staticinline__attribute__((always_inline))voidblock_set_size(block_header_t*block,size_tsize){constsize_toldsize=block->size;block->size=size|(oldsize&(block_header_free_bit|block_header_prev_free_bit));}{ ... }staticinline__attribute__((always_inline))intblock_is_last(constblock_header_t*block){returnblock_size(block)==0;}{ ... }staticinline__attribute__((always_inline))intblock_is_free(constblock_header_t*block){returntlsf_cast(int,block->size&block_header_free_bit);}{ ... }staticinline__attribute__((always_inline))voidblock_set_free(block_header_t*block){block->size|=block_header_free_bit;}{ ... }staticinline__attribute__((always_inline))voidblock_set_used(block_header_t*block){block->size&=~block_header_free_bit;}{ ... }staticinline__attribute__((always_inline))intblock_is_prev_free(constblock_header_t*block){returntlsf_cast(int,block->size&block_header_prev_free_bit);}{ ... }staticinline__attribute__((always_inline))voidblock_set_prev_free(block_header_t*block){block->size|=block_header_prev_free_bit;}{ ... }staticinline__attribute__((always_inline))voidblock_set_prev_used(block_header_t*block){block->size&=~block_header_prev_free_bit;}{ ... }staticinline__attribute__((always_inline))block_header_t*block_from_ptr(constvoid*ptr){returntlsf_cast(block_header_t*,tlsf_cast(unsignedchar*,ptr)-block_start_offset);}{ ... }staticinline__attribute__((always_inline))void*block_to_ptr(constblock_header_t*block){returntlsf_cast(void*,tlsf_cast(unsignedchar*,block)+block_start_offset);}{ ... }/* Return location of next block after block of given size. */staticinline__attribute__((always_inline))block_header_t*offset_to_block(constvoid*ptr,size_tsize){returntlsf_cast(block_header_t*,tlsf_cast(tlsfptr_t,ptr)+size);}{ ... }/* Return location of previous block. */staticinline__attribute__((always_inline))block_header_t*block_prev(constblock_header_t*block){tlsf_assert(block_is_prev_free(block)&&"previous block must be free");returnblock->prev_phys_block;}{ ... }/* Return location of next existing block. */staticinline__attribute__((always_inline))block_header_t*block_next(constblock_header_t*block){block_header_t*next=offset_to_block(block_to_ptr(block),block_size(block)-block_header_overhead);tlsf_assert(!block_is_last(block));returnnext;}{ ... }/* Link a new block with its physical neighbor, return the neighbor. */staticinline__attribute__((always_inline))block_header_t*block_link_next(block_header_t*block){block_header_t*next=block_next(block);next->prev_phys_block=block;returnnext;}{ ... }staticinline__attribute__((always_inline))voidblock_mark_as_free(block_header_t*block){/* Link the block to the next block, first. */block_header_t*next=block_link_next(block);block_set_prev_free(next);block_set_free(block);}{ ... }staticinline__attribute__((always_inline))voidblock_mark_as_used(block_header_t*block){block_header_t*next=block_next(block);block_set_prev_used(next);block_set_used(block);}{ ... }#ifdefined(__cplusplus)}{...};#endif
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.