From: Vladimír Čunát Date: Tue, 24 May 2022 09:35:14 +0000 (+0200) Subject: tweak inlining X-Git-Tag: v5.5.1~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5bd8a765bd9b959064c22c20ff6f62a60ab4e1de;p=thirdparty%2Fknot-resolver.git tweak inlining I used -Winline (optimizing, gcc 11 or 12) to gather warnings about cases that were considered too expensive for inlining. Some of these probably used not to happen when we were dropping assertions during preprocessing in -DNDEBUG builds. This commit mainly improves size of the compiled binary by several KiB. - queue_head_impl(): optionally (un)inline; not big but in warnings - queue_pop_impl(): uninline; too complex for my today's eyes - kr_rand_bytes(): optionally (un)inline The inlining potential there comes from calling with a constant. - kr_straddr(): uninline. It's never been meant for hot code, and this gives us large savings due to deduplicating the static array. - For some I couldn't see a good resolution due to restrictions in C. C hint: `static inline` is probably well known; the other inline combination is well explained at: https://stackoverflow.com/a/6312813/587396 --- diff --git a/lib/generic/queue.c b/lib/generic/queue.c index 7a458cd38..883487524 100644 --- a/lib/generic/queue.c +++ b/lib/generic/queue.c @@ -5,6 +5,8 @@ #include "lib/generic/queue.h" #include +extern inline void * queue_head_impl(const struct queue *q); + void queue_init_impl(struct queue *q, size_t item_size) { q->len = 0; @@ -114,3 +116,25 @@ void * queue_push_head_impl(struct queue *q) return h->data + q->item_size * h->begin; } +void queue_pop_impl(struct queue *q) +{ + kr_require(q); + struct queue_chunk *h = q->head; + kr_require(h && h->end > h->begin); + if (h->end - h->begin == 1) { + /* removing the last element in the chunk */ + kr_require((q->len == 1) == (q->head == q->tail)); + if (q->len == 1) { + q->tail = NULL; + kr_require(!h->next); + } else { + kr_require(h->next); + } + q->head = h->next; + free(h); + } else { + ++(h->begin); + } + --(q->len); +} + diff --git a/lib/generic/queue.h b/lib/generic/queue.h index 1a65b0528..034e5266e 100644 --- a/lib/generic/queue.h +++ b/lib/generic/queue.h @@ -146,6 +146,7 @@ KR_EXPORT void queue_init_impl(struct queue *q, size_t item_size); KR_EXPORT void queue_deinit_impl(struct queue *q); KR_EXPORT void * queue_push_impl(struct queue *q); KR_EXPORT void * queue_push_head_impl(struct queue *q); +KR_EXPORT void queue_pop_impl(struct queue *q); struct queue_chunk; struct queue { @@ -172,7 +173,7 @@ struct queue_chunk { */ }; -static inline void * queue_head_impl(const struct queue *q) +KR_EXPORT inline void * queue_head_impl(const struct queue *q) { kr_require(q); struct queue_chunk *h = q->head; @@ -188,29 +189,6 @@ static inline void * queue_tail_impl(const struct queue *q) return t->data + (t->end - 1) * q->item_size; } -static inline void queue_pop_impl(struct queue *q) -{ - kr_require(q); - struct queue_chunk *h = q->head; - kr_require(h && h->end > h->begin); - if (h->end - h->begin == 1) { - /* removing the last element in the chunk */ - kr_require((q->len == 1) == (q->head == q->tail)); - if (q->len == 1) { - q->tail = NULL; - kr_require(!h->next); - } else { - kr_require(h->next); - } - q->head = h->next; - free(h); - } else { - ++(h->begin); - } - --(q->len); -} - - struct queue_it { struct queue_chunk *chunk; int16_t pos, item_size; diff --git a/lib/utils.c b/lib/utils.c index 4eaef3625..46d3fb65a 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -51,6 +51,8 @@ struct __attribute((packed)) kr_sockaddr_un_key { char path[sizeof(((struct sockaddr_un *) NULL)->sun_path)]; }; +extern inline uint64_t kr_rand_bytes(unsigned int size); + /* Logging & debugging */ bool kr_dbg_assertion_abort = DBG_ASSERTION_ABORT; int kr_dbg_assertion_fork = DBG_ASSERTION_FORK; @@ -521,6 +523,19 @@ int kr_ntop_str(int family, const void *src, uint16_t port, char *buf, size_t *b return kr_ok(); } +char *kr_straddr(const struct sockaddr *addr) +{ + if (kr_fails_assert(addr)) return NULL; + static char str[KR_STRADDR_MAXLEN + 1] = {0}; + if (addr->sa_family == AF_UNIX) { + strncpy(str, ((struct sockaddr_un *)addr)->sun_path, sizeof(str) - 1); + return str; + } + size_t len = KR_STRADDR_MAXLEN; + int ret = kr_inaddr_str(addr, str, &len); + return ret != kr_ok() || len == 0 ? NULL : str; +} + int kr_straddr_family(const char *addr) { if (!addr) { diff --git a/lib/utils.h b/lib/utils.h index 49cd4a8dc..cede7bef3 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -185,7 +185,8 @@ KR_EXPORT void kr_rnd_buffered(void *data, unsigned int size); /** Return a few random bytes. */ -static inline uint64_t kr_rand_bytes(unsigned int size) +KR_EXPORT inline +uint64_t kr_rand_bytes(unsigned int size) { uint64_t result; if (size <= 0 || size > sizeof(result)) { @@ -320,22 +321,10 @@ KR_EXPORT int kr_ntop_str(int family, const void *src, uint16_t port, char *buf, size_t *buflen); /** @internal Create string representation addr#port. - * @return pointer to static string + * @return pointer to a *static* string, i.e. each call will overwrite it */ -static inline char *kr_straddr(const struct sockaddr *addr) -{ - if (kr_fails_assert(addr)) return NULL; - /* We are the single-threaded application */ - static char str[KR_STRADDR_MAXLEN + 1] = {0}; - if (addr->sa_family == AF_UNIX) { - strncpy(str, ((struct sockaddr_un *) addr)->sun_path, sizeof(str) - 1); - return str; - } - size_t len = KR_STRADDR_MAXLEN; - int ret = kr_inaddr_str(addr, str, &len); - return ret != kr_ok() || len == 0 ? NULL : str; -} - +KR_EXPORT +char *kr_straddr(const struct sockaddr *addr); /** Return address type for string. */ KR_EXPORT KR_PURE