[PATCH 30/34] ptrlist: simplify common case for __add_ptr_list()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The vast majority of pointer list use non-tagged pointer,
the core library and the sparse tool doesn't use them
(in fact only 'example.c' use them).

The current functions to add a pointer to a ptr_list suppose
that all pointers are tagged and in the case of non-word-aligned
pointers (strings) it create a a fake tag consiting of the last
2 bits.

This patch siplify the situation by separating the common case
(non-tagged or non-word-aligned pointers) which ignore the presence
of a tag and make another version which check and combien the tag
with the pointer before calling the common case.
---
 ptrlist.c | 30 +++++++++++++++++++++++-------
 ptrlist.h | 11 +++++------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/ptrlist.c b/ptrlist.c
index 1957baf1f..95447eaea 100644
--- a/ptrlist.c
+++ b/ptrlist.c
@@ -114,18 +114,19 @@ void split_ptr_list_head(struct ptr_list *head)
 	memset(head->list + old, 0xf0, nr * sizeof(void *));
 }
 
-void **__add_ptr_list(struct ptr_list **listp, void *ptr, unsigned long tag)
+/*
+ * Add 'ptr' to 'listp'.
+ * 'ptr' can be a tagged pointer, a non-tagged one or a
+ * non-word-aligned one, it doesn't matter.
+ * Returns the address where 'ptr' was stored.
+ */
+void **__add_ptr_list(struct ptr_list **listp, void *ptr)
 {
 	struct ptr_list *list = *listp;
 	struct ptr_list *last = NULL; /* gcc complains needlessly */
 	void **ret;
 	int nr;
 
-	/* The low two bits are reserved for tags */
-	assert((3 & (unsigned long)ptr) == 0);
-	assert((~3 & tag) == 0);
-	ptr = (void *)(tag | (unsigned long)ptr);
-
 	if (!list || (nr = (last = list->prev)->nr) >= LIST_NODE_NR) {
 		struct ptr_list *newlist = __alloc_ptrlist(0);
 		if (!list) {
@@ -148,6 +149,21 @@ void **__add_ptr_list(struct ptr_list **listp, void *ptr, unsigned long tag)
 	return ret;
 }
 
+/*
+ * Add 'ptr' to 'listp' and tag it with 'tag'
+ * 'ptr' must be a non-tagged word-aligned pointer.
+ * Returns the address where 'ptr' was stored.
+ */
+void **__add_ptr_list_tag(struct ptr_list **listp, void *ptr, unsigned long tag)
+{
+	/* The low two bits are reserved for tags */
+	assert((3 & (unsigned long)ptr) == 0);
+	assert((~3 & tag) == 0);
+	ptr = (void *)(tag | (unsigned long)ptr);
+
+	return __add_ptr_list(listp, ptr);
+}
+
 int delete_ptr_list_entry(struct ptr_list **list, void *entry, int count)
 {
 	struct ptr_cur cur;
@@ -234,7 +250,7 @@ void concat_ptr_list(struct ptr_list *a, struct ptr_list **b)
                 return;
 
 	while (ptr_cur_next(&cur))
-		__add_ptr_list(b, ptr_cur_entry(&cur), 0);
+		__add_ptr_list(b, ptr_cur_entry(&cur));
 }
 
 void __free_ptr_list(struct ptr_list **listp)
diff --git a/ptrlist.h b/ptrlist.h
index c1d53632d..9e16adb36 100644
--- a/ptrlist.h
+++ b/ptrlist.h
@@ -45,7 +45,8 @@ int delete_ptr_list_entry(struct ptr_list **, void *, int);
 int replace_ptr_list_entry(struct ptr_list **, void *old, void *new, int);
 extern void sort_list(struct ptr_list **, int (*)(const void *, const void *));
 
-extern void **__add_ptr_list(struct ptr_list **, void *, unsigned long);
+extern void **__add_ptr_list(struct ptr_list **, void *);
+extern void **__add_ptr_list_tag(struct ptr_list **, void *, unsigned long);
 extern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b);
 extern void __free_ptr_list(struct ptr_list **);
 extern int ptr_list_size(struct ptr_list *);
@@ -65,13 +66,11 @@ void ptr_cur_delete(struct ptr_cur *cur, void *ptr);
  * extensions..
  */
 #define add_ptr_list_tag(list,entry,tag) \
-	MKTYPE(*(list), (CHECK_TYPE(*(list),(entry)),__add_ptr_list((struct ptr_list **)(list), (entry), (tag))))
+	MKTYPE(*(list), (CHECK_TYPE(*(list),(entry)),__add_ptr_list_tag((struct ptr_list **)(list), (entry), (tag))))
 #define add_ptr_list_notag(list,entry)										\
-	MKTYPE(*(list), (CHECK_TYPE(*(list),(entry)),__add_ptr_list((struct ptr_list **)(list),			\
-								    (void *)((unsigned long)(entry) & ~3UL), 	\
-								    (unsigned long)(entry) & 3)))
+	MKTYPE(*(list), (CHECK_TYPE(*(list),(entry)),__add_ptr_list((struct ptr_list **)(list),	 (entry))))
 #define add_ptr_list(list,entry) \
-	add_ptr_list_tag(list,entry,0)
+	add_ptr_list_notag(list,entry)
 #define free_ptr_list(list) \
 	do { VRFY_PTR_LIST(*(list)); __free_ptr_list((struct ptr_list **)(list)); } while (0)
 
-- 
2.13.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux