summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-02-11 20:54:18 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-11 21:02:22 +0000
commit87bed52180cd2abd80ef6b58384f9fd9c9968f7b (patch)
treed35094099d6d160932f5c66134ce49b557a5a55d
parentc64ebee5fdccf313cbd3c73850e02e6fa7dd2a65 (diff)
Include a local copy of list.h
In 1.11.903, the list.h was renamed to xorg-list.h with a corresponding change to all structures. As we carried local fixes to list.h and extended functionality, just create our own list.h with a bit of handwaving to protect us for the brief existence of xorg/include/list.h. Reported-by: Armin K <krejzi@email.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45938 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/Makefile.am1
-rw-r--r--src/intel.h90
-rw-r--r--src/intel_list.h407
-rw-r--r--src/intel_uxa.c4
-rw-r--r--src/sna/Makefile.am17
-rw-r--r--src/sna/kgem.c34
-rw-r--r--src/sna/sna.h7
-rw-r--r--src/sna/sna_accel.c8
8 files changed, 421 insertions, 147 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a6325435..448a354e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,7 @@ endif
NULL:=#
intel_drv_la_SOURCES = \
+ intel_list.h \
intel_module.c \
$(NULL)
diff --git a/src/intel.h b/src/intel.h
index 7593731b..8104bfed 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -68,100 +68,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i915_drm.h"
#include "intel_driver.h"
+#include "intel_list.h"
#if HAVE_UDEV
#include <libudev.h>
#endif
-/* XXX
- * The X server gained an *almost* identical implementation in 1.9.
- *
- * Remove this duplicate code either in 2.16 (when we can depend upon 1.9)
- * or the drivers are merged back into the xserver tree, whichever happens
- * earlier.
- */
-
-#ifndef _LIST_H_
-/* classic doubly-link circular list */
-struct list {
- struct list *next, *prev;
-};
-
-static void
-list_init(struct list *list)
-{
- list->next = list->prev = list;
-}
-
-static inline void
-__list_add(struct list *entry,
- struct list *prev,
- struct list *next)
-{
- next->prev = entry;
- entry->next = next;
- entry->prev = prev;
- prev->next = entry;
-}
-
-static inline void
-list_add(struct list *entry, struct list *head)
-{
- __list_add(entry, head, head->next);
-}
-
-static inline void
-__list_del(struct list *prev, struct list *next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-static inline void
-list_del(struct list *entry)
-{
- __list_del(entry->prev, entry->next);
- list_init(entry);
-}
-
-static inline Bool
-list_is_empty(struct list *head)
-{
- return head->next == head;
-}
-#endif
-
-/* XXX work around a broken define in list.h currently [ickle 20100713] */
-#undef container_of
-
-#ifndef container_of
-#define container_of(ptr, type, member) \
- ((type *)((char *)(ptr) - (char *) &((type *)0)->member))
-#endif
-
-#ifndef list_entry
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-#endif
-
-#ifndef list_first_entry
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-#endif
-
-#ifndef list_foreach
-#define list_foreach(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-#endif
-
-/* XXX list.h from xserver-1.9 uses a GCC-ism to avoid having to pass type */
-#ifndef list_foreach_entry
-#define list_foreach_entry(pos, type, head, member) \
- for (pos = list_entry((head)->next, type, member);\
- &pos->member != (head); \
- pos = list_entry(pos->member.next, type, member))
-#endif
-
/* remain compatible to xorg-server 1.6 */
#ifndef MONITOR_EDID_COMPLETE_RAWDATA
#define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA
diff --git a/src/intel_list.h b/src/intel_list.h
new file mode 100644
index 00000000..2595a298
--- /dev/null
+++ b/src/intel_list.h
@@ -0,0 +1,407 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _INTEL_LIST_H_
+#define _INTEL_LIST_H_
+
+#include <xorgVersion.h>
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,0,0,0) || XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,11,99,903,0)
+
+#include <stdbool.h>
+
+/**
+ * @file Classic doubly-link circular list implementation.
+ * For real usage examples of the linked list, see the file test/list.c
+ *
+ * Example:
+ * We need to keep a list of struct foo in the parent struct bar, i.e. what
+ * we want is something like this.
+ *
+ * struct bar {
+ * ...
+ * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
+ * ...
+ * }
+ *
+ * We need one list head in bar and a list element in all list_of_foos (both are of
+ * data type 'struct list').
+ *
+ * struct bar {
+ * ...
+ * struct list list_of_foos;
+ * ...
+ * }
+ *
+ * struct foo {
+ * ...
+ * struct list entry;
+ * ...
+ * }
+ *
+ * Now we initialize the list head:
+ *
+ * struct bar bar;
+ * ...
+ * list_init(&bar.list_of_foos);
+ *
+ * Then we create the first element and add it to this list:
+ *
+ * struct foo *foo = malloc(...);
+ * ....
+ * list_add(&foo->entry, &bar.list_of_foos);
+ *
+ * Repeat the above for each element you want to add to the list. Deleting
+ * works with the element itself.
+ * list_del(&foo->entry);
+ * free(foo);
+ *
+ * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
+ * list again.
+ *
+ * Looping through the list requires a 'struct foo' as iterator and the
+ * name of the field the subnodes use.
+ *
+ * struct foo *iterator;
+ * list_for_each_entry(iterator, &bar.list_of_foos, entry) {
+ * if (iterator->something == ...)
+ * ...
+ * }
+ *
+ * Note: You must not call list_del() on the iterator if you continue the
+ * loop. You need to run the safe for-each loop instead:
+ *
+ * struct foo *iterator, *next;
+ * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
+ * if (...)
+ * list_del(&iterator->entry);
+ * }
+ *
+ */
+
+/**
+ * The linkage struct for list nodes. This struct must be part of your
+ * to-be-linked struct. struct list is required for both the head of the
+ * list and for each list node.
+ *
+ * Position and name of the struct list field is irrelevant.
+ * There are no requirements that elements of a list are of the same type.
+ * There are no requirements for a list head, any struct list can be a list
+ * head.
+ */
+struct list {
+ struct list *next, *prev;
+};
+
+/**
+ * Initialize the list as an empty list.
+ *
+ * Example:
+ * list_init(&bar->list_of_foos);
+ *
+ * @param The list to initialized.
+ */
+static void
+list_init(struct list *list)
+{
+ list->next = list->prev = list;
+}
+
+static inline void
+__list_add(struct list *entry,
+ struct list *prev,
+ struct list *next)
+{
+ next->prev = entry;
+ entry->next = next;
+ entry->prev = prev;
+ prev->next = entry;
+}
+
+/**
+ * Insert a new element after the given list head. The new element does not
+ * need to be initialised as empty list.
+ * The list changes from:
+ * head → some element → ...
+ * to
+ * head → new element → older element → ...
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * list_add(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+list_add(struct list *entry, struct list *head)
+{
+ __list_add(entry, head, head->next);
+}
+
+static inline void
+list_add_tail(struct list *entry, struct list *head)
+{
+ __list_add(entry, head->prev, head);
+}
+
+static inline void list_replace(struct list *old,
+ struct list *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * Append a new element to the end of the list given with this list head.
+ *
+ * The list changes from:
+ * head → some element → ... → lastelement
+ * to
+ * head → some element → ... → lastelement → new element
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * list_append(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+list_append(struct list *entry, struct list *head)
+{
+ __list_add(entry, head->prev, head);
+}
+
+
+static inline void
+__list_del(struct list *prev, struct list *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+_list_del(struct list *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+/**
+ * Remove the element from the list it is in. Using this function will reset
+ * the pointers to/from this element so it is removed from the list. It does
+ * NOT free the element itself or manipulate it otherwise.
+ *
+ * Using list_del on a pure list head (like in the example at the top of
+ * this file) will NOT remove the first element from
+ * the list but rather reset the list as empty list.
+ *
+ * Example:
+ * list_del(&foo->entry);
+ *
+ * @param entry The element to remove.
+ */
+static inline void
+list_del(struct list *entry)
+{
+ _list_del(entry);
+ list_init(entry);
+}
+
+static inline void list_move(struct list *list, struct list *head)
+{
+ if (list->prev != head) {
+ _list_del(list);
+ list_add(list, head);
+ }
+}
+
+static inline void list_move_tail(struct list *list, struct list *head)
+{
+ _list_del(list);
+ list_add_tail(list, head);
+}
+
+/**
+ * Check if the list is empty.
+ *
+ * Example:
+ * list_is_empty(&bar->list_of_foos);
+ *
+ * @return True if the list contains one or more elements or False otherwise.
+ */
+static inline bool
+list_is_empty(struct list *head)
+{
+ return head->next == head;
+}
+
+/**
+ * Returns a pointer to the container of this list element.
+ *
+ * Example:
+ * struct foo* f;
+ * f = container_of(&foo->entry, struct foo, entry);
+ * assert(f == foo);
+ *
+ * @param ptr Pointer to the struct list.
+ * @param type Data type of the list element.
+ * @param member Member name of the struct list field in the list element.
+ * @return A pointer to the data struct containing the list head.
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) \
+ ((type *)((char *)(ptr) - (char *) &((type *)0)->member))
+#endif
+
+/**
+ * Alias of container_of
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * Retrieve the first list entry for the given list pointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct list field in the list element.
+ * @return A pointer to the first list element.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * Retrieve the last list entry for the given listpointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct list field in the list element.
+ * @return A pointer to the last list element.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+#define __container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) \
+ - ((char *)&(sample)->member - (char *)(sample)))
+/**
+ * Loop through the list given by head and set pos to struct in the list.
+ *
+ * Example:
+ * struct foo *iterator;
+ * list_for_each_entry(iterator, &bar->list_of_foos, entry) {
+ * [modify iterator]
+ * }
+ *
+ * This macro is not safe for node deletion. Use list_for_each_entry_safe
+ * instead.
+ *
+ * @param pos Iterator variable of the type of the list elements.
+ * @param head List head
+ * @param member Member name of the struct list in the list elements.
+ *
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = __container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+/**
+ * Loop through the list, keeping a backup pointer to the element. This
+ * macro allows for the deletion of a list element while looping through the
+ * list.
+ *
+ * See list_for_each_entry for more details.
+ */
+#define list_for_each_entry_safe(pos, tmp, head, member) \
+ for (pos = __container_of((head)->next, pos, member), \
+ tmp = __container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
+
+#else
+
+#include <list.h>
+
+static inline void
+list_add_tail(struct list *entry, struct list *head)
+{
+ __list_add(entry, head->prev, head);
+}
+
+static inline void
+_list_del(struct list *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+static inline void list_replace(struct list *old,
+ struct list *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void list_move(struct list *list, struct list *head)
+{
+ if (list->prev != head) {
+ _list_del(list);
+ list_add(list, head);
+ }
+}
+
+static inline void list_move_tail(struct list *list, struct list *head)
+{
+ _list_del(list);
+ list_add_tail(list, head);
+}
+
+#undef container_of
+#define container_of(ptr, type, member) \
+ ((type *)((char *)(ptr) - (char *) &((type *)0)->member))
+
+#endif
+
+#endif /* _INTEL_LIST_H_ */
+
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index a11846d0..0cb8df37 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -1092,9 +1092,7 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
else
aligned_h = ALIGN(h, 2);
- list_foreach_entry(priv, struct intel_pixmap,
- &intel->in_flight,
- in_flight) {
+ list_for_each_entry(priv, &intel->in_flight, in_flight) {
if (priv->tiling != tiling)
continue;
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index 2809617d..70afd532 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -18,18 +18,19 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-AM_CFLAGS = @CWARNFLAGS@ @XORG_CFLAGS@ \
- @UDEV_CFLAGS@ \
- @DRM_CFLAGS@ \
- @DRI_CFLAGS@ \
- -I$(top_srcdir)/src \
- -I$(top_srcdir)/src/render_program
+AM_CFLAGS = \
+ @CWARNFLAGS@ \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/render_program \
+ @XORG_CFLAGS@ \
+ @UDEV_CFLAGS@ \
+ @DRM_CFLAGS@ \
+ @DRI_CFLAGS@ \
+ $(NULL)
noinst_LTLIBRARIES = libsna.la
libsna_la_LIBADD = @UDEV_LIBS@ -lm @DRM_LIBS@
-NULL:=#
-
libsna_la_SOURCES = \
blt.c \
compiler.h \
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 607f1c45..f20a7bb1 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -51,40 +51,6 @@
static struct kgem_bo *
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
-static inline void _list_del(struct list *list)
-{
- assert(list->prev->next == list);
- assert(list->next->prev == list);
- __list_del(list->prev, list->next);
-}
-
-static inline void list_move(struct list *list, struct list *head)
-{
- _list_del(list);
- list_add(list, head);
-}
-
-static inline void list_move_tail(struct list *list, struct list *head)
-{
- _list_del(list);
- list_add_tail(list, head);
-}
-
-static inline void list_replace(struct list *old,
- struct list *new)
-{
- new->next = old->next;
- new->next->prev = new;
- new->prev = old->prev;
- new->prev->next = new;
-}
-
-#define list_last_entry(ptr, type, member) \
- list_entry((ptr)->prev, type, member)
-
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
#define DBG_NO_HW 0
#define DBG_NO_TILING 0
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 73e24908..575c213c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -44,6 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdint.h>
#include "compiler.h"
+
#include <xf86_OSproc.h>
#include <xf86Pci.h>
#include <xf86Cursor.h>
@@ -109,15 +110,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define TEST_RENDER (TEST_ALL || 0)
#include "intel_driver.h"
+#include "intel_list.h"
#include "kgem.h"
#include "sna_damage.h"
#include "sna_render.h"
-static inline void list_add_tail(struct list *new, struct list *head)
-{
- __list_add(new, head->prev, head);
-}
-
#ifndef CREATE_PIXMAP_USAGE_SCRATCH_HEADER
#define FAKE_CREATE_PIXMAP_USAGE_SCRATCH_HEADER 1
#define CREATE_PIXMAP_USAGE_SCRATCH_HEADER (unsigned)-1
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 2a4aaecc..23fc9adf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -815,14 +815,6 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
return fbDestroyPixmap(pixmap);
}
-static inline void list_move(struct list *list, struct list *head)
-{
- if (list->prev != head) {
- __list_del(list->prev, list->next);
- list_add(list, head);
- }
-}
-
static inline bool pixmap_inplace(struct sna *sna,
PixmapPtr pixmap,
struct sna_pixmap *priv)