diff options
Diffstat (limited to 'libnetdata/libnetdata.h')
-rw-r--r-- | libnetdata/libnetdata.h | 185 |
1 files changed, 173 insertions, 12 deletions
diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h index 58eaa9de..c504bd4b 100644 --- a/libnetdata/libnetdata.h +++ b/libnetdata/libnetdata.h @@ -11,10 +11,18 @@ extern "C" { #include <config.h> #endif +#define JUDYHS_INDEX_SIZE_ESTIMATE(key_bytes) (((key_bytes) + sizeof(Word_t) - 1) / sizeof(Word_t) * 4) + #if defined(NETDATA_DEV_MODE) && !defined(NETDATA_INTERNAL_CHECKS) #define NETDATA_INTERNAL_CHECKS 1 #endif +#if SIZEOF_VOID_P == 4 +#define ENV32BIT 1 +#else +#define ENV64BIT 1 +#endif + // NETDATA_TRACE_ALLOCATIONS does not work under musl libc, so don't enable it //#if defined(NETDATA_INTERNAL_CHECKS) && !defined(NETDATA_TRACE_ALLOCATIONS) //#define NETDATA_TRACE_ALLOCATIONS 1 @@ -217,6 +225,10 @@ extern "C" { #define WARNUNUSED #endif +void aral_judy_init(void); +size_t judy_aral_overhead(void); +size_t judy_aral_structures(void); + #define ABS(x) (((x) < 0)? (-(x)) : (x)) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) @@ -225,8 +237,9 @@ extern "C" { // --------------------------------------------------------------------------------------------- // double linked list management +// inspired by https://github.com/troydhanson/uthash/blob/master/src/utlist.h -#define DOUBLE_LINKED_LIST_PREPEND_UNSAFE(head, item, prev, next) \ +#define DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(head, item, prev, next) \ do { \ (item)->next = (head); \ \ @@ -240,7 +253,7 @@ extern "C" { (head) = (item); \ } while (0) -#define DOUBLE_LINKED_LIST_APPEND_UNSAFE(head, item, prev, next) \ +#define DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(head, item, prev, next) \ do { \ if(likely(head)) { \ (item)->prev = (head)->prev; \ @@ -256,39 +269,97 @@ extern "C" { \ } while (0) -#define DOUBLE_LINKED_LIST_REMOVE_UNSAFE(head, item, prev, next) \ +#define DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(head, item, prev, next) \ do { \ fatal_assert((head) != NULL); \ fatal_assert((item)->prev != NULL); \ \ - if((item)->prev == (item)) { \ + if((item)->prev == (item)) \ /* it is the only item in the list */ \ (head) = NULL; \ - } \ + \ else if((item) == (head)) { \ /* it is the first item */ \ + fatal_assert((item)->next != NULL); \ (item)->next->prev = (item)->prev; \ (head) = (item)->next; \ } \ else { \ + /* it is any other item */ \ (item)->prev->next = (item)->next; \ - if ((item)->next) { \ + \ + if ((item)->next) \ (item)->next->prev = (item)->prev; \ - } \ - else { \ + else \ (head)->prev = (item)->prev; \ - } \ } \ \ (item)->next = NULL; \ (item)->prev = NULL; \ } while (0) +#define DOUBLE_LINKED_LIST_INSERT_ITEM_BEFORE_UNSAFE(head, existing, item, prev, next) \ + do { \ + if (existing) { \ + fatal_assert((head) != NULL); \ + fatal_assert((item) != NULL); \ + \ + (item)->next = (existing); \ + (item)->prev = (existing)->prev; \ + (existing)->prev = (item); \ + \ + if ((head) == (existing)) \ + (head) = (item); \ + else \ + (item)->prev->next = (item); \ + \ + } \ + else \ + DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(head, item, prev, next); \ + \ + } while (0) + +#define DOUBLE_LINKED_LIST_INSERT_ITEM_AFTER_UNSAFE(head, existing, item, prev, next) \ + do { \ + if (existing) { \ + fatal_assert((head) != NULL); \ + fatal_assert((item) != NULL); \ + \ + (item)->next = (existing)->next; \ + (item)->prev = (existing); \ + (existing)->next = (item); \ + \ + if ((item)->next) \ + (item)->next->prev = (item); \ + else \ + (head)->prev = (item); \ + } \ + else \ + DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(head, item, prev, next); \ + \ + } while (0) + +#define DOUBLE_LINKED_LIST_APPEND_LIST_UNSAFE(head, head2, prev, next) \ + do { \ + if (head2) { \ + if (head) { \ + __typeof(head2) _head2_last_item = (head2)->prev; \ + \ + (head2)->prev = (head)->prev; \ + (head)->prev->next = (head2); \ + \ + (head)->prev = _head2_last_item; \ + } \ + else \ + (head) = (head2); \ + } \ + } while (0) + #define DOUBLE_LINKED_LIST_FOREACH_FORWARD(head, var, prev, next) \ for ((var) = (head); (var) ; (var) = (var)->next) #define DOUBLE_LINKED_LIST_FOREACH_BACKWARD(head, var, prev, next) \ - for ((var) = (head)?(head)->prev:NULL; (var) && (var) != (head)->prev ; (var) = (var)->prev) + for ((var) = (head) ? (head)->prev : NULL ; (var) ; (var) = ((var) == (head)) ? NULL : (var)->prev) // --------------------------------------------------------------------------------------------- @@ -301,6 +372,14 @@ char *mystrsep(char **ptr, char *s); char *trim(char *s); // remove leading and trailing spaces; may return NULL char *trim_all(char *buffer); // like trim(), but also remove duplicate spaces inside the string; may return NULL +int madvise_sequential(void *mem, size_t len); +int madvise_random(void *mem, size_t len); +int madvise_dontfork(void *mem, size_t len); +int madvise_willneed(void *mem, size_t len); +int madvise_dontneed(void *mem, size_t len); +int madvise_dontdump(void *mem, size_t len); +int madvise_mergeable(void *mem, size_t len); + int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args); int snprintfz(char *dst, size_t n, const char *fmt, ...) PRINTFLIKE(3, 4); @@ -335,7 +414,7 @@ void posix_memfree(void *ptr); void json_escape_string(char *dst, const char *src, size_t size); void json_fix_string(char *s); -void *netdata_mmap(const char *filename, size_t size, int flags, int ksm); +void *netdata_mmap(const char *filename, size_t size, int flags, int ksm, bool read_only, int *open_fd); int netdata_munmap(void *ptr, size_t size); int memory_file_save(const char *filename, void *mem, size_t size); @@ -418,10 +497,22 @@ static inline char *get_word(char **words, size_t num_words, size_t index) { bool run_command_and_copy_output_to_stdout(const char *command, int max_line_length); +typedef enum { + OPEN_FD_ACTION_CLOSE, + OPEN_FD_ACTION_FD_CLOEXEC +} OPEN_FD_ACTION; +typedef enum { + OPEN_FD_EXCLUDE_STDIN = 0x01, + OPEN_FD_EXCLUDE_STDOUT = 0x02, + OPEN_FD_EXCLUDE_STDERR = 0x04 +} OPEN_FD_EXCLUDE; +void for_each_open_fd(OPEN_FD_ACTION action, OPEN_FD_EXCLUDE excluded_fds); + void netdata_cleanup_and_exit(int ret) NORETURN; void send_statistics(const char *action, const char *action_result, const char *action_data); extern char *netdata_configured_host_prefix; #include "libjudy/src/Judy.h" +#include "july/july.h" #include "os.h" #include "storage_number/storage_number.h" #include "threads/threads.h" @@ -453,7 +544,7 @@ extern char *netdata_configured_host_prefix; #include "json/json.h" #include "health/health.h" #include "string/utf8.h" -#include "arrayalloc/arrayalloc.h" +#include "libnetdata/aral/aral.h" #include "onewayalloc/onewayalloc.h" #include "worker_utilization/worker_utilization.h" @@ -500,6 +591,76 @@ struct malloc_trace { }; #endif // NETDATA_TRACE_ALLOCATIONS +static inline PPvoid_t JudyLFirstThenNext(Pcvoid_t PArray, Word_t * PIndex, bool *first) { + if(unlikely(*first)) { + *first = false; + return JudyLFirst(PArray, PIndex, PJE0); + } + + return JudyLNext(PArray, PIndex, PJE0); +} + +static inline PPvoid_t JudyLLastThenPrev(Pcvoid_t PArray, Word_t * PIndex, bool *first) { + if(unlikely(*first)) { + *first = false; + return JudyLLast(PArray, PIndex, PJE0); + } + + return JudyLPrev(PArray, PIndex, PJE0); +} + +static inline size_t indexing_partition_old(Word_t ptr, Word_t modulo) { + size_t total = 0; + + total += (ptr & 0xff) >> 0; + total += (ptr & 0xff00) >> 8; + total += (ptr & 0xff0000) >> 16; + total += (ptr & 0xff000000) >> 24; + + if(sizeof(Word_t) > 4) { + total += (ptr & 0xff00000000) >> 32; + total += (ptr & 0xff0000000000) >> 40; + total += (ptr & 0xff000000000000) >> 48; + total += (ptr & 0xff00000000000000) >> 56; + } + + return (total % modulo); +} + +static uint32_t murmur32(uint32_t h) __attribute__((const)); +static inline uint32_t murmur32(uint32_t h) { + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +static uint64_t murmur64(uint64_t h) __attribute__((const)); +static inline uint64_t murmur64(uint64_t k) { + k ^= k >> 33; + k *= 0xff51afd7ed558ccdUL; + k ^= k >> 33; + k *= 0xc4ceb9fe1a85ec53UL; + k ^= k >> 33; + + return k; +} + +static inline size_t indexing_partition(Word_t ptr, Word_t modulo) __attribute__((const)); +static inline size_t indexing_partition(Word_t ptr, Word_t modulo) { + if(sizeof(Word_t) == 8) { + uint64_t hash = murmur64(ptr); + return hash % modulo; + } + else { + uint32_t hash = murmur32(ptr); + return hash % modulo; + } +} + # ifdef __cplusplus } # endif |