2021-02-18 20:46:25 +00:00
# ifndef YALLOC_INTERNALS_H
# define YALLOC_INTERNALS_H
# include <stdint.h>
typedef struct
{
2021-02-18 20:55:03 +00:00
uint32_t prev ; // low bit set if free
uint32_t next ; // for used blocks: low bit set if unused header at the end
2021-04-18 12:57:00 +00:00
/* We need user data to be 32-byte aligned, so the header needs
* to be 32 bytes in size ( as user data follows the header ) */
uint8_t padding [ 32 - ( sizeof ( uint32_t ) * 2 ) ] ;
2021-02-18 20:46:25 +00:00
} Header ;
// NOTE: We have 32bit aligned data and 16bit offsets where the lowest bit is used as flag. So we remove the low bit and shift by 1 to address 128k bytes with the 15bit significant offset bits.
2021-02-18 20:55:03 +00:00
# define NIL 0xFFFFFFFEu
2021-02-18 20:46:25 +00:00
// return Header-address for a prev/next
# define HDR_PTR(offset) ((Header*)((char*)pool + (((offset) & NIL)<<1)))
// return a prev/next for a Header-address
2021-02-18 20:55:03 +00:00
# define HDR_OFFSET(blockPtr) ((uint32_t)(((char*)blockPtr - (char*)pool) >> 1))
2021-02-18 20:46:25 +00:00
# ifndef YALLOC_INTERNAL_VALIDATE
# ifdef NDEBUG
# define YALLOC_INTERNAL_VALIDATE 0
# else
# define YALLOC_INTERNAL_VALIDATE 1
# endif
# endif
/*
internal_assert ( ) is used in some places to check internal expections .
Activate this if you modify the code to detect problems as early as possible .
In other cases this should be deactivated .
*/
#if 0
# define internal_assert assert
# else
# define internal_assert(condition)((void) 0)
# endif
// detects offsets that point nowhere
2021-02-18 20:55:03 +00:00
static inline int isNil ( uint32_t offset )
2021-02-18 20:46:25 +00:00
{
2021-02-18 20:55:03 +00:00
return ( offset | 1 ) = = 0xFFFFFFFF ;
2021-02-18 20:46:25 +00:00
}
static inline int isFree ( Header * hdr )
{
return hdr - > prev & 1 ;
}
static inline int isPadded ( Header * hdr )
{
return hdr - > next & 1 ;
}
# endif // YALLOC_INTERNALS_H