Message ID | 20190627104836.25446-2-hch@lst.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/13] list.h: add list_pop and list_pop_entry helpers | expand |
On Thu, Jun 27, 2019 at 12:48:24PM +0200, Christoph Hellwig wrote: > We have a very common pattern where we want to delete the first entry > from a list and return it as the properly typed container structure. > > Add two helpers to implement this behavior. > > Signed-off-by: Christoph Hellwig <hch@lst.de> LGTM, Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > --- > include/linux/list.h | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/include/linux/list.h b/include/linux/list.h > index e951228db4b2..ba6e27d2235a 100644 > --- a/include/linux/list.h > +++ b/include/linux/list.h > @@ -500,6 +500,39 @@ static inline void list_splice_tail_init(struct list_head *list, > pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ > }) > > +/** > + * list_pop - delete the first entry from a list and return it > + * @list: the list to take the element from. > + * > + * Return the list entry after @list. If @list is empty return NULL. > + */ > +static inline struct list_head *list_pop(struct list_head *list) > +{ > + struct list_head *pos = READ_ONCE(list->next); > + > + if (pos == list) > + return NULL; > + list_del(pos); > + return pos; > +} > + > +/** > + * list_pop_entry - delete the first entry from a list and return the > + * containing structure > + * @list: the list to take the element from. > + * @type: the type of the struct this is embedded in. > + * @member: the name of the list_head within the struct. > + * > + * Return the containing structure for the list entry after @list. If @list > + * is empty return NULL. > + */ > +#define list_pop_entry(list, type, member) \ > +({ \ > + struct list_head *pos__ = list_pop(list); \ > + \ > + pos__ ? list_entry(pos__, type, member) : NULL; \ > +}) > + > /** > * list_next_entry - get the next element in list > * @pos: the type * to cursor > -- > 2.20.1 >
diff --git a/include/linux/list.h b/include/linux/list.h index e951228db4b2..ba6e27d2235a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -500,6 +500,39 @@ static inline void list_splice_tail_init(struct list_head *list, pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ }) +/** + * list_pop - delete the first entry from a list and return it + * @list: the list to take the element from. + * + * Return the list entry after @list. If @list is empty return NULL. + */ +static inline struct list_head *list_pop(struct list_head *list) +{ + struct list_head *pos = READ_ONCE(list->next); + + if (pos == list) + return NULL; + list_del(pos); + return pos; +} + +/** + * list_pop_entry - delete the first entry from a list and return the + * containing structure + * @list: the list to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Return the containing structure for the list entry after @list. If @list + * is empty return NULL. + */ +#define list_pop_entry(list, type, member) \ +({ \ + struct list_head *pos__ = list_pop(list); \ + \ + pos__ ? list_entry(pos__, type, member) : NULL; \ +}) + /** * list_next_entry - get the next element in list * @pos: the type * to cursor
We have a very common pattern where we want to delete the first entry from a list and return it as the properly typed container structure. Add two helpers to implement this behavior. Signed-off-by: Christoph Hellwig <hch@lst.de> --- include/linux/list.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)