All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Zbigniew Kempczyński" <zbigniew.kempczynski@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Subject: [igt-dev] [PATCH i-g-t 01/24] lib/igt_list: igt_hlist implementation.
Date: Thu, 22 Oct 2020 11:58:44 +0200	[thread overview]
Message-ID: <20201022095907.34225-2-zbigniew.kempczynski@intel.com> (raw)
In-Reply-To: <20201022095907.34225-1-zbigniew.kempczynski@intel.com>

From: Dominik Grzegorzek <dominik.grzegorzek@intel.com>

Double linked lists with a single pointer list head implementation,
based on similar in the kernel.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 lib/igt_list.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_list.h | 50 +++++++++++++++++++++++++++++++++--
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/lib/igt_list.c b/lib/igt_list.c
index 5e30b19b..60eb571c 100644
--- a/lib/igt_list.c
+++ b/lib/igt_list.c
@@ -75,3 +75,74 @@ bool igt_list_empty(const struct igt_list_head *head)
 {
 	return head->next == head;
 }
+
+void IGT_INIT_HLIST_NODE(struct igt_hlist_node *h)
+{
+	h->next = NULL;
+	h->pprev = NULL;
+}
+
+int igt_hlist_unhashed(const struct igt_hlist_node *h)
+{
+	return !h->pprev;
+}
+
+int igt_hlist_empty(const struct igt_hlist_head *h)
+{
+	return !h->first;
+}
+
+static void __igt_hlist_del(struct igt_hlist_node *n)
+{
+	struct igt_hlist_node *next = n->next;
+	struct igt_hlist_node **pprev = n->pprev;
+
+	*pprev = next;
+	if (next)
+		next->pprev = pprev;
+}
+
+void igt_hlist_del(struct igt_hlist_node *n)
+{
+	__igt_hlist_del(n);
+	n->next = NULL;
+	n->pprev = NULL;
+}
+
+void igt_hlist_del_init(struct igt_hlist_node *n)
+{
+	if (!igt_hlist_unhashed(n)) {
+		__igt_hlist_del(n);
+		IGT_INIT_HLIST_NODE(n);
+	}
+}
+
+void igt_hlist_add_head(struct igt_hlist_node *n, struct igt_hlist_head *h)
+{
+	struct igt_hlist_node *first = h->first;
+
+	n->next = first;
+	if (first)
+		first->pprev = &n->next;
+	h->first = n;
+	n->pprev = &h->first;
+}
+
+/* next must be != NULL */
+void igt_hlist_add_before(struct igt_hlist_node *n, struct igt_hlist_node *next)
+{
+	n->pprev = next->pprev;
+	n->next = next;
+	next->pprev = &n->next;
+	*(n->pprev) = n;
+}
+
+void igt_hlist_add_behind(struct igt_hlist_node *n, struct igt_hlist_node *prev)
+{
+	n->next = prev->next;
+	prev->next = n;
+	n->pprev = &prev->next;
+
+	if (n->next)
+		n->next->pprev  = &n->next;
+}
diff --git a/lib/igt_list.h b/lib/igt_list.h
index dbf5f802..d910fde7 100644
--- a/lib/igt_list.h
+++ b/lib/igt_list.h
@@ -40,6 +40,10 @@
  * igt_list is a doubly-linked list where an instance of igt_list_head is a
  * head sentinel and has to be initialized.
  *
+ * igt_hist is also an double linked lists, but with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful. You lose the ability to access the tail in O(1).
+ *
  * Example usage:
  *
  * |[<!-- language="C" -->
@@ -71,6 +75,13 @@ struct igt_list_head {
 	struct igt_list_head *next;
 };
 
+struct igt_hlist_head {
+	struct igt_hlist_node *first;
+};
+
+struct igt_hlist_node {
+	struct igt_hlist_node *next, **pprev;
+};
 
 void IGT_INIT_LIST_HEAD(struct igt_list_head *head);
 void igt_list_add(struct igt_list_head *elem, struct igt_list_head *head);
@@ -80,6 +91,17 @@ void igt_list_move_tail(struct igt_list_head *elem, struct igt_list_head *list);
 int igt_list_length(const struct igt_list_head *head);
 bool igt_list_empty(const struct igt_list_head *head);
 
+void IGT_INIT_HLIST_NODE(struct igt_hlist_node *h);
+int igt_hlist_unhashed(const struct igt_hlist_node *h);
+int igt_hlist_empty(const struct igt_hlist_head *h);
+void igt_hlist_del(struct igt_hlist_node *n);
+void igt_hlist_del_init(struct igt_hlist_node *n);
+void igt_hlist_add_head(struct igt_hlist_node *n, struct igt_hlist_head *h);
+void igt_hlist_add_before(struct igt_hlist_node *n,
+			  struct igt_hlist_node *next);
+void igt_hlist_add_behind(struct igt_hlist_node *n,
+			  struct igt_hlist_node *prev);
+
 #define igt_container_of(ptr, sample, member)				\
 	(__typeof__(sample))((char *)(ptr) -				\
 				offsetof(__typeof__(*sample), member))
@@ -95,9 +117,10 @@ bool igt_list_empty(const struct igt_list_head *head);
  * Safe against removel of the *current* list element. To achive this it
  * requires an extra helper variable `tmp` with the same type as `pos`.
  */
-#define igt_list_for_each_entry_safe(pos, tmp, head, member)			\
+
+#define igt_list_for_each_entry_safe(pos, tmp, head, member)		\
 	for (pos = igt_container_of((head)->next, pos, member),		\
-	     tmp = igt_container_of((pos)->member.next, tmp, member); 	\
+	     tmp = igt_container_of((pos)->member.next, tmp, member);	\
 	     &pos->member != (head);					\
 	     pos = tmp,							\
 	     tmp = igt_container_of((pos)->member.next, tmp, member))
@@ -107,6 +130,27 @@ bool igt_list_empty(const struct igt_list_head *head);
 	     &pos->member != (head);					\
 	     pos = igt_container_of((pos)->member.prev, pos, member))
 
+#define igt_list_for_each_entry_safe_reverse(pos, tmp, head, member)		\
+	for (pos = igt_container_of((head)->prev, pos, member),		\
+	     tmp = igt_container_of((pos)->member.prev, tmp, member);	\
+	     &pos->member != (head);					\
+	     pos = tmp,							\
+	     tmp = igt_container_of((pos)->member.prev, tmp, member))
+
+#define igt_hlist_entry_safe(ptr, sample, member) \
+	({ typeof(ptr) ____ptr = (ptr); \
+	   ____ptr ? igt_container_of(____ptr, sample, member) : NULL; \
+	})
+
+#define igt_hlist_for_each_entry(pos, head, member)			\
+	for (pos = igt_hlist_entry_safe((head)->first, pos, member);	\
+	     pos;							\
+	     pos = igt_hlist_entry_safe((pos)->member.next, pos, member))
+
+#define igt_hlist_for_each_entry_safe(pos, n, head, member)		\
+	for (pos = igt_hlist_entry_safe((head)->first, pos, member);	\
+	     pos && ({ n = pos->member.next; 1; });			\
+	     pos = igt_hlist_entry_safe(n, pos, member))
 
 /* IGT custom helpers */
 
@@ -126,4 +170,6 @@ bool igt_list_empty(const struct igt_list_head *head);
 #define igt_list_last_entry(head, type, member) \
 	igt_container_of((head)->prev, (type), member)
 
+#define IGT_INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+
 #endif /* IGT_LIST_H */
-- 
2.26.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2020-10-22  9:59 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-22  9:58 [igt-dev] [PATCH i-g-t 00/24] Introduce IGT allocator Zbigniew Kempczyński
2020-10-22  9:58 ` Zbigniew Kempczyński [this message]
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 02/24] lib/igt_map: Introduce igt_map Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 03/24] lib/igt_core: Track child process pid and tid Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 04/24] lib/intel_allocator_simple: Add simple allocator Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 05/24] lib/intel_allocator_random: Add random allocator Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 06/24] lib/intel_allocator: Add intel_allocator core Zbigniew Kempczyński
2020-10-22 10:09   ` Petri Latvala
2020-10-22 10:13     ` Chris Wilson
2020-10-22 10:14   ` Chris Wilson
2020-10-22 15:51     ` Jani Nikula
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 07/24] lib/intel_allocator: Try to stop smoothly instead of deinit Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 08/24] lib/intel_allocator_msgchannel: Scale to 4k of parallel clients Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 09/24] lib/intel_bufops: Removes handle from allocator, change size Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 10/24] lib/intel_bufops: Add init with handle and size function Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 11/24] lib/intel_batchbuffer: Integrate intel_bb with allocator Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 12/24] lib/intel_batchbuffer: Add tracking intel_buf to intel_bb Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 13/24] lib/intel_aux_pgtable: Get addresses for aux table from an allocator Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 14/24] lib/igt_fb: Initialize intel_buf with same size as fb Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 15/24] tests/api_intel_bb: Modify test to verify intel_bb with allocator Zbigniew Kempczyński
2020-10-22  9:58 ` [igt-dev] [PATCH i-g-t 16/24] tests/api_intel_bb: Add compressed->compressed copy Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 17/24] tests/api_intel_allocator: Simple allocator test suite Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 18/24] tests/gem|kms: Remove intel_bb from fixture Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 19/24] tests/gem_mmap_offset: Use intel_buf wrapper code instead direct Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 20/24] tests/gem_ppgtt: Adopt test to use intel_bb with allocator Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 21/24] tests/gem_render_copy_redux: Adopt to use with intel_bb and allocator Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 22/24] tests/perf.c: Remove buffer from batch Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 23/24] tests/gem_linear_blits: Use intel allocator Zbigniew Kempczyński
2020-10-22  9:59 ` [igt-dev] [PATCH i-g-t 24/24] lib/intel_batchbuffer.c: Debug bb in CI Zbigniew Kempczyński
2020-10-22 10:51 ` [igt-dev] ✓ Fi.CI.BAT: success for Introduce IGT allocator Patchwork
2020-10-22 14:04 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201022095907.34225-2-zbigniew.kempczynski@intel.com \
    --to=zbigniew.kempczynski@intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.