From: Willy Tarreau Date: Tue, 28 Jan 2014 22:04:39 +0000 (+0100) Subject: MINOR: tools: add very basic support for composite pointers X-Git-Tag: v1.5-dev22~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bb519c7cd145454b8a1f8ad20e5acabfa436c7ea;p=thirdparty%2Fhaproxy.git MINOR: tools: add very basic support for composite pointers Very often we want to associate one or two flags to a pointer, to put a type on it or whatever. This patch provides this in standard.h in the form of a few inline functions which combine a void * pointer with an int and return an unsigned long called a composite address. The functions allow to individuall set, retrieve both the pointer and the flags. This is very similar to what is used in ebtree in fact. --- diff --git a/include/common/standard.h b/include/common/standard.h index c4c5d64f17..14b0eba9b8 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -776,4 +776,54 @@ static inline void shut_your_big_mouth_gcc(int r) /* same as strstr() but case-insensitive */ const char *strnistr(const char *str1, int len_str1, const char *str2, int len_str2); + +/************************* Composite address manipulation ********************* + * Composite addresses are simply unsigned long data in which the higher bits + * represent a pointer, and the two lower bits are flags. There are several + * places where we just want to associate one or two flags to a pointer (eg, + * to type it), and these functions permit this. The pointer is necessarily a + * 32-bit aligned pointer, as its two lower bits will be cleared and replaced + * with the flags. + *****************************************************************************/ + +/* Masks the two lower bits of a composite address and converts it to a + * pointer. This is used to mix some bits with some aligned pointers to + * structs and to retrieve the original (32-bit aligned) pointer. + */ +static inline void *caddr_to_ptr(unsigned long caddr) +{ + return (void *)(caddr & ~3UL); +} + +/* Only retrieves the two lower bits of a composite address. This is used to mix + * some bits with some aligned pointers to structs and to retrieve the original + * data (2 bits). + */ +static inline unsigned int caddr_to_data(unsigned long caddr) +{ + return (caddr & 3UL); +} + +/* Combines the aligned pointer whose 2 lower bits will be masked with the bits + * from to form a composite address. This is used to mix some bits with + * some aligned pointers to structs and to retrieve the original (32-bit aligned) + * pointer. + */ +static inline unsigned long caddr_from_ptr(void *ptr, unsigned int data) +{ + return (((unsigned long)ptr) & ~3UL) + (data & 3); +} + +/* sets the 2 bits of in the composite address */ +static inline unsigned long caddr_set_flags(unsigned long caddr, unsigned int data) +{ + return caddr | (data & 3); +} + +/* clears the 2 bits of in the composite address */ +static inline unsigned long caddr_clr_flags(unsigned long caddr, unsigned int data) +{ + return caddr & ~(unsigned long)(data & 3); +} + #endif /* _COMMON_STANDARD_H */