X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=include%2Furcu%2Fhlist.h;fp=include%2Furcu%2Fhlist.h;h=5e3c27d02025bd4445efd65606f60374d8326e88;hp=344481133eac2051f4d7ab85e6188f51887e7dd7;hb=a0b5ef6802894441aae058f9a34628b565a35846;hpb=3abcdbd14d1b9291f06a4a4bbca313fcfbe5452b diff --git a/include/urcu/hlist.h b/include/urcu/hlist.h index 3444811..5e3c27d 100644 --- a/include/urcu/hlist.h +++ b/include/urcu/hlist.h @@ -17,6 +17,7 @@ */ #include +#include struct cds_hlist_head { struct cds_hlist_node *next; @@ -40,8 +41,14 @@ void CDS_INIT_HLIST_HEAD(struct cds_hlist_head *ptr) { .next = NULL } /* Get typed element from list at a given position. */ -#define cds_hlist_entry(ptr, type, member) \ - ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) +#define cds_hlist_entry(ptr, type, member) caa_container_of(ptr, type, member) + +/* Get typed element from list at a given position, keeping NULL pointers. */ +#define cds_hlist_entry_safe(ptr, type, member) \ + ({ \ + __typeof__(ptr) ____ret = ptr; \ + ____ret ? cds_hlist_entry(____ret, type, member) : NULL; \ + }) /* Add new element at the head of the list. */ static inline @@ -93,17 +100,13 @@ void cds_hlist_del(struct cds_hlist_node *elem) entry = cds_hlist_entry(pos, __typeof__(*entry), member)) #define cds_hlist_for_each_entry_2(entry, head, member) \ - for (entry = ((head)->next == NULL ? NULL \ - : cds_hlist_entry((head)->next, __typeof__(*entry), member)); \ + for (entry = cds_hlist_entry_safe((head)->next, __typeof__(*entry), member); \ entry != NULL; \ - entry = (entry->member.next == NULL ? NULL \ - : cds_hlist_entry(entry->member.next, __typeof__(*entry), member))) + entry = cds_hlist_entry_safe(entry->member.next, __typeof__(*entry), member)) #define cds_hlist_for_each_entry_safe_2(entry, e, head, member) \ - for (entry = ((head)->next == NULL ? NULL \ - : cds_hlist_entry((head)->next, __typeof__(*entry), member)); \ - (entry != NULL) && (e = (entry->member.next == NULL ? NULL \ - : cds_hlist_entry(entry->member.next, \ + for (entry = cds_hlist_entry_safe((head)->next, __typeof__(*entry), member); \ + (entry != NULL) && (e = (cds_hlist_entry_safe(entry->member.next, \ __typeof__(*entry), member)), 1); \ entry = e)