mempool: use list.h API
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 12 Apr 2024 19:20:35 +0000 (15:20 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 12 Apr 2024 19:20:35 +0000 (15:20 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I2cabb4b8b6ff70cd111961335c0306b0ec76e827

src/Makefile.am
src/list.h [new file with mode: 0644]
src/rseq-mempool.c
tests/Makefile.am
tests/list.h [deleted file]
tests/mempool_test.c

index e313f27fcab4f8b08fe1575facfdbf9a268eb6aa..424192a16144c285e72ebc8a9a7ff9e593222482 100644 (file)
@@ -4,7 +4,7 @@
 lib_LTLIBRARIES = librseq.la
 
 librseq_la_SOURCES = \
-       rseq.c rseq-mempool.c rseq-utils.h smp.c smp.h
+       rseq.c rseq-mempool.c rseq-utils.h smp.c smp.h list.h
 
 librseq_la_LDFLAGS = -no-undefined -version-info $(RSEQ_LIBRARY_VERSION)
 librseq_la_LIBADD = $(DL_LIBS)
diff --git a/src/list.h b/src/list.h
new file mode 100644 (file)
index 0000000..39a456b
--- /dev/null
@@ -0,0 +1,198 @@
+// SPDX-FileCopyrightText: 2002 Free Software Foundation, Inc.
+// SPDX-FileCopyrightText: 2009 Pierre-Marc Fournier
+// SPDX-FileCopyrightText: 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+/*
+ * (originally part of the GNU C Library)
+ * Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+ */
+
+#ifndef _LIST_H
+#define _LIST_H        1
+
+/*
+ * container_of - Get the address of an object containing a field.
+ *
+ * @ptr: pointer to the field.
+ * @type: type of the object.
+ * @member: name of the field within the object.
+ */
+#define container_of(ptr, type, member)                                        \
+       __extension__                                                   \
+       ({                                                              \
+               const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
+               (type *)((char *)__ptr - offsetof(type, member));       \
+       })
+
+/*
+ * The definitions of this file are adopted from those which can be
+ * found in the Linux kernel headers to enable people familiar with the
+ * latter find their way in these sources as well.
+ */
+
+/* Basic type for the double-link list. */
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+/* Define a variable with the head and tail of the list. */
+#define LIST_HEAD(name) \
+       struct list_head name = { &(name), &(name) }
+
+/* Initialize a new list head. */
+#define INIT_LIST_HEAD(ptr) \
+       (ptr)->next = (ptr)->prev = (ptr)
+
+#define LIST_HEAD_INIT(name) { .next = &(name), .prev = &(name) }
+
+/* Add new element at the head of the list. */
+static inline
+void list_add(struct list_head *newp, struct list_head *head)
+{
+       head->next->prev = newp;
+       newp->next = head->next;
+       newp->prev = head;
+       head->next = newp;
+}
+
+/* Add new element at the tail of the list. */
+static inline
+void list_add_tail(struct list_head *newp, struct list_head *head)
+{
+       head->prev->next = newp;
+       newp->next = head;
+       newp->prev = head->prev;
+       head->prev = newp;
+}
+
+/* Remove element from list. */
+static inline
+void __list_del(struct list_head *prev, struct list_head *next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/* Remove element from list. */
+static inline
+void list_del(struct list_head *elem)
+{
+       __list_del(elem->prev, elem->next);
+}
+
+/* Remove element from list, initializing the element's list pointers. */
+static inline
+void list_del_init(struct list_head *elem)
+{
+       list_del(elem);
+       INIT_LIST_HEAD(elem);
+}
+
+/* Delete from list, add to another list as head. */
+static inline
+void list_move(struct list_head *elem, struct list_head *head)
+{
+       __list_del(elem->prev, elem->next);
+       list_add(elem, head);
+}
+
+/* Replace an old entry. */
+static inline
+void list_replace(struct list_head *old, struct list_head *_new)
+{
+       _new->next = old->next;
+       _new->prev = old->prev;
+       _new->prev->next = _new;
+       _new->next->prev = _new;
+}
+
+/* Join two lists. */
+static inline
+void list_splice(struct list_head *add, struct list_head *head)
+{
+       /* Do nothing if the list which gets added is empty. */
+       if (add != add->next) {
+               add->next->prev = head;
+               add->prev->next = head->next;
+               head->next->prev = add->prev;
+               head->next = add->next;
+       }
+}
+
+/* Get typed element from list at a given position. */
+#define list_entry(ptr, type, member)  container_of(ptr, type, member)
+
+/* Get first entry from a list. */
+#define list_first_entry(ptr, type, member) \
+       list_entry((ptr)->next, type, member)
+
+/* Iterate forward over the elements of the list. */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next; (pos) != (head); pos = (pos)->next)
+
+/*
+ * Iterate forward over the elements list. The list elements can be
+ * removed from the list while doing this.
+ */
+#define list_for_each_safe(pos, p, head) \
+       for (pos = (head)->next, p = (pos)->next; \
+               (pos) != (head); \
+               pos = (p), p = (pos)->next)
+
+/* Iterate backward over the elements of the list. */
+#define list_for_each_prev(pos, head) \
+       for (pos = (head)->prev; (pos) != (head); pos = (pos)->prev)
+
+/*
+ * Iterate backwards over the elements list. The list elements can be
+ * removed from the list while doing this.
+ */
+#define list_for_each_prev_safe(pos, p, head) \
+       for (pos = (head)->prev, p = (pos)->prev; \
+               (pos) != (head); \
+               pos = (p), p = (pos)->prev)
+
+#define list_for_each_entry(pos, head, member) \
+       for (pos = list_entry((head)->next, __typeof__(*(pos)), member); \
+               &(pos)->member != (head); \
+               pos = list_entry((pos)->member.next, __typeof__(*(pos)), member))
+
+#define list_for_each_entry_reverse(pos, head, member) \
+       for (pos = list_entry((head)->prev, __typeof__(*(pos)), member); \
+               &(pos)->member != (head); \
+               pos = list_entry((pos)->member.prev, __typeof__(*(pos)), member))
+
+#define list_for_each_entry_safe(pos, p, head, member) \
+       for (pos = list_entry((head)->next, __typeof__(*(pos)), member), \
+                       p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \
+               &(pos)->member != (head); \
+               pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member))
+
+/*
+ * Same as list_for_each_entry_safe, but starts from "pos" which should
+ * point to an entry within the list.
+ */
+#define list_for_each_entry_safe_from(pos, p, head, member) \
+        for (p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \
+                &(pos)->member != (head); \
+                pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member))
+
+static inline
+int list_empty(struct list_head *head)
+{
+       return head == head->next;
+}
+
+static inline
+void list_replace_init(struct list_head *old, struct list_head *_new)
+{
+       struct list_head *head = old->next;
+
+       list_del(old);
+       list_add_tail(_new, head);
+       INIT_LIST_HEAD(old);
+}
+
+#endif /* _LIST_H */
index 83b317dd83ec1476335d1b27f5ef4675770b76e4..ee38e26d8e3dc6fd361d0e1e473473cf9a8e8e22 100644 (file)
@@ -22,6 +22,7 @@
 #endif
 
 #include "rseq-utils.h"
+#include "list.h"
 #include <rseq/rseq.h>
 
 /*
@@ -101,7 +102,7 @@ struct rseq_mempool_attr {
 struct rseq_mempool_range;
 
 struct rseq_mempool_range {
-       struct rseq_mempool_range *next;        /* Linked list of ranges. */
+       struct list_head node;                  /* Linked list of ranges. */
        struct rseq_mempool *pool;              /* Backward reference to container pool. */
 
        /*
@@ -144,8 +145,7 @@ struct rseq_mempool_range {
 };
 
 struct rseq_mempool {
-       /* Head of ranges linked-list. */
-       struct rseq_mempool_range *range_list;
+       struct list_head range_list;    /* Head of ranges linked-list. */
        unsigned long nr_ranges;
 
        size_t item_len;
@@ -493,7 +493,7 @@ bool percpu_addr_in_pool(const struct rseq_mempool *pool, void __rseq_percpu *_a
        struct rseq_mempool_range *range;
        void *addr = (void *) _addr;
 
-       for (range = pool->range_list; range; range = range->next) {
+       list_for_each_entry(range, &pool->range_list, node) {
                if (addr >= range->base && addr < range->base + range->next_unused)
                        return true;
        }
@@ -511,7 +511,7 @@ void check_free_list(const struct rseq_mempool *pool, bool mapping_accessible)
        if (!pool->attr.robust_set || !mapping_accessible)
                return;
 
-       for (range = pool->range_list; range; range = range->next) {
+       list_for_each_entry(range, &pool->range_list, node) {
                total_item += pool->attr.stride >> pool->item_order;
                total_never_allocated += (pool->attr.stride - range->next_unused) >> pool->item_order;
        }
@@ -570,7 +570,7 @@ void check_pool_poison(const struct rseq_mempool *pool, bool mapping_accessible)
 
        if (!pool->attr.robust_set || !mapping_accessible)
                return;
-       for (range = pool->range_list; range; range = range->next)
+       list_for_each_entry(range, &pool->range_list, node)
                check_range_poison(pool, range);
 }
 
@@ -872,9 +872,9 @@ bool pool_mappings_accessible(struct rseq_mempool *pool)
 
        if (pool->attr.populate_policy != RSEQ_MEMPOOL_POPULATE_COW_INIT)
                return true;
-       range = pool->range_list;
-       if (!range)
+       if (list_empty(&pool->range_list))
                return true;
+       range = list_first_entry(&pool->range_list, struct rseq_mempool_range, node);
        page_size = rseq_get_page_len();
        /*
         * Header first page is one page before the page containing the
@@ -891,7 +891,7 @@ bool pool_mappings_accessible(struct rseq_mempool *pool)
 
 int rseq_mempool_destroy(struct rseq_mempool *pool)
 {
-       struct rseq_mempool_range *range, *next_range;
+       struct rseq_mempool_range *range, *tmp_range;
        bool mapping_accessible;
        int ret = 0;
 
@@ -910,11 +910,13 @@ int rseq_mempool_destroy(struct rseq_mempool *pool)
        check_pool_poison(pool, mapping_accessible);
 
        /* Iteration safe against removal. */
-       for (range = pool->range_list; range && (next_range = range->next, 1); range = next_range) {
-               if (rseq_mempool_range_destroy(pool, range, mapping_accessible))
+       list_for_each_entry_safe(range, tmp_range, &pool->range_list, node) {
+               list_del(&range->node);
+               if (rseq_mempool_range_destroy(pool, range, mapping_accessible)) {
+                       /* Keep list coherent in case of partial failure. */
+                       list_add(&range->node, &pool->range_list);
                        goto end;
-               /* Update list head to keep list coherent in case of partial failure. */
-               pool->range_list = next_range;
+               }
        }
        pthread_mutex_destroy(&pool->lock);
        free(pool->name);
@@ -926,8 +928,9 @@ end:
 struct rseq_mempool *rseq_mempool_create(const char *pool_name,
                size_t item_len, const struct rseq_mempool_attr *_attr)
 {
-       struct rseq_mempool *pool;
        struct rseq_mempool_attr attr = {};
+       struct rseq_mempool_range *range;
+       struct rseq_mempool *pool;
        int order;
 
        /* Make sure each item is large enough to contain free list pointers. */
@@ -1004,10 +1007,12 @@ struct rseq_mempool *rseq_mempool_create(const char *pool_name,
        pthread_mutex_init(&pool->lock, NULL);
        pool->item_len = item_len;
        pool->item_order = order;
+       INIT_LIST_HEAD(&pool->range_list);
 
-       pool->range_list = rseq_mempool_range_create(pool);
-       if (!pool->range_list)
+       range = rseq_mempool_range_create(pool);
+       if (!range)
                goto error_alloc;
+       list_add(&range->node, &pool->range_list);
 
        if (pool_name) {
                pool->name = strdup(pool_name);
@@ -1080,7 +1085,7 @@ void __rseq_percpu *__rseq_percpu_malloc(struct rseq_mempool *pool,
         * room left, create a new range and prepend it to the list
         * head.
         */
-       range = pool->range_list;
+       range = list_first_entry(&pool->range_list, struct rseq_mempool_range, node);
        if (range->next_unused + pool->item_len > pool->attr.stride) {
                range = rseq_mempool_range_create(pool);
                if (!range) {
@@ -1089,8 +1094,7 @@ void __rseq_percpu *__rseq_percpu_malloc(struct rseq_mempool *pool,
                        goto end;
                }
                /* Add range to head of list. */
-               range->next = pool->range_list;
-               pool->range_list = range;
+               list_add(&range->node, &pool->range_list);
        }
        /* First range in list has room left. */
        item_offset = range->next_unused;
index 1a50a726eeffd9ebeeb1f6e7411d94cd2f9445a5..2cc71e82d6d8eeaedb98d09a4ad8b2cab55ef27a 100644 (file)
@@ -90,10 +90,10 @@ basic_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/util
 basic_test_cxx_tap_SOURCES = basic_test_cxx.cpp
 basic_test_cxx_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
 
-mempool_test_tap_SOURCES = mempool_test.c list.h
+mempool_test_tap_SOURCES = mempool_test.c
 mempool_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
 
-mempool_test_cxx_tap_SOURCES = mempool_test_cxx.cpp list.h
+mempool_test_cxx_tap_SOURCES = mempool_test_cxx.cpp
 mempool_test_cxx_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
 
 mempool_cow_race_test_tap_SOURCES = mempool_cow_race_test.c
diff --git a/tests/list.h b/tests/list.h
deleted file mode 100644 (file)
index 39a456b..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-FileCopyrightText: 2002 Free Software Foundation, Inc.
-// SPDX-FileCopyrightText: 2009 Pierre-Marc Fournier
-// SPDX-FileCopyrightText: 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-//
-// SPDX-License-Identifier: LGPL-2.1-or-later
-
-/*
- * (originally part of the GNU C Library)
- * Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
- */
-
-#ifndef _LIST_H
-#define _LIST_H        1
-
-/*
- * container_of - Get the address of an object containing a field.
- *
- * @ptr: pointer to the field.
- * @type: type of the object.
- * @member: name of the field within the object.
- */
-#define container_of(ptr, type, member)                                        \
-       __extension__                                                   \
-       ({                                                              \
-               const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
-               (type *)((char *)__ptr - offsetof(type, member));       \
-       })
-
-/*
- * The definitions of this file are adopted from those which can be
- * found in the Linux kernel headers to enable people familiar with the
- * latter find their way in these sources as well.
- */
-
-/* Basic type for the double-link list. */
-struct list_head {
-       struct list_head *next, *prev;
-};
-
-/* Define a variable with the head and tail of the list. */
-#define LIST_HEAD(name) \
-       struct list_head name = { &(name), &(name) }
-
-/* Initialize a new list head. */
-#define INIT_LIST_HEAD(ptr) \
-       (ptr)->next = (ptr)->prev = (ptr)
-
-#define LIST_HEAD_INIT(name) { .next = &(name), .prev = &(name) }
-
-/* Add new element at the head of the list. */
-static inline
-void list_add(struct list_head *newp, struct list_head *head)
-{
-       head->next->prev = newp;
-       newp->next = head->next;
-       newp->prev = head;
-       head->next = newp;
-}
-
-/* Add new element at the tail of the list. */
-static inline
-void list_add_tail(struct list_head *newp, struct list_head *head)
-{
-       head->prev->next = newp;
-       newp->next = head;
-       newp->prev = head->prev;
-       head->prev = newp;
-}
-
-/* Remove element from list. */
-static inline
-void __list_del(struct list_head *prev, struct list_head *next)
-{
-       next->prev = prev;
-       prev->next = next;
-}
-
-/* Remove element from list. */
-static inline
-void list_del(struct list_head *elem)
-{
-       __list_del(elem->prev, elem->next);
-}
-
-/* Remove element from list, initializing the element's list pointers. */
-static inline
-void list_del_init(struct list_head *elem)
-{
-       list_del(elem);
-       INIT_LIST_HEAD(elem);
-}
-
-/* Delete from list, add to another list as head. */
-static inline
-void list_move(struct list_head *elem, struct list_head *head)
-{
-       __list_del(elem->prev, elem->next);
-       list_add(elem, head);
-}
-
-/* Replace an old entry. */
-static inline
-void list_replace(struct list_head *old, struct list_head *_new)
-{
-       _new->next = old->next;
-       _new->prev = old->prev;
-       _new->prev->next = _new;
-       _new->next->prev = _new;
-}
-
-/* Join two lists. */
-static inline
-void list_splice(struct list_head *add, struct list_head *head)
-{
-       /* Do nothing if the list which gets added is empty. */
-       if (add != add->next) {
-               add->next->prev = head;
-               add->prev->next = head->next;
-               head->next->prev = add->prev;
-               head->next = add->next;
-       }
-}
-
-/* Get typed element from list at a given position. */
-#define list_entry(ptr, type, member)  container_of(ptr, type, member)
-
-/* Get first entry from a list. */
-#define list_first_entry(ptr, type, member) \
-       list_entry((ptr)->next, type, member)
-
-/* Iterate forward over the elements of the list. */
-#define list_for_each(pos, head) \
-       for (pos = (head)->next; (pos) != (head); pos = (pos)->next)
-
-/*
- * Iterate forward over the elements list. The list elements can be
- * removed from the list while doing this.
- */
-#define list_for_each_safe(pos, p, head) \
-       for (pos = (head)->next, p = (pos)->next; \
-               (pos) != (head); \
-               pos = (p), p = (pos)->next)
-
-/* Iterate backward over the elements of the list. */
-#define list_for_each_prev(pos, head) \
-       for (pos = (head)->prev; (pos) != (head); pos = (pos)->prev)
-
-/*
- * Iterate backwards over the elements list. The list elements can be
- * removed from the list while doing this.
- */
-#define list_for_each_prev_safe(pos, p, head) \
-       for (pos = (head)->prev, p = (pos)->prev; \
-               (pos) != (head); \
-               pos = (p), p = (pos)->prev)
-
-#define list_for_each_entry(pos, head, member) \
-       for (pos = list_entry((head)->next, __typeof__(*(pos)), member); \
-               &(pos)->member != (head); \
-               pos = list_entry((pos)->member.next, __typeof__(*(pos)), member))
-
-#define list_for_each_entry_reverse(pos, head, member) \
-       for (pos = list_entry((head)->prev, __typeof__(*(pos)), member); \
-               &(pos)->member != (head); \
-               pos = list_entry((pos)->member.prev, __typeof__(*(pos)), member))
-
-#define list_for_each_entry_safe(pos, p, head, member) \
-       for (pos = list_entry((head)->next, __typeof__(*(pos)), member), \
-                       p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \
-               &(pos)->member != (head); \
-               pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member))
-
-/*
- * Same as list_for_each_entry_safe, but starts from "pos" which should
- * point to an entry within the list.
- */
-#define list_for_each_entry_safe_from(pos, p, head, member) \
-        for (p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \
-                &(pos)->member != (head); \
-                pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member))
-
-static inline
-int list_empty(struct list_head *head)
-{
-       return head == head->next;
-}
-
-static inline
-void list_replace_init(struct list_head *old, struct list_head *_new)
-{
-       struct list_head *head = old->next;
-
-       list_del(old);
-       list_add_tail(_new, head);
-       INIT_LIST_HEAD(old);
-}
-
-#endif /* _LIST_H */
index 42654dd2c547d65457dc000a7cd17ed539e43dd5..3fe102974191117d68d6909cd4378bec1c49ae72 100644 (file)
@@ -21,7 +21,7 @@
 #include <rseq/mempool.h>
 #include "../src/rseq-utils.h"
 
-#include "list.h"
+#include "../src/list.h"
 #include "tap.h"
 
 #if RSEQ_BITS_PER_LONG == 64
This page took 0.038373 seconds and 4 git commands to generate.