11/* Singly-linked list
22 * – Two sentinel nodes (head and tail) eliminate edge-case tests.
33 * – The list stores generic data pointers ('void *').
4- * – All primitives are defined ` static inline` so they can live entirely
4+ * – All primitives are defined ' static inline' so they can live entirely
55 * in the header without multiple-definition issues.
6- * – Comments follow C style and use concise American English.
76 */
87
98#pragma once
109
1110#include <lib/libc.h>
1211#include <lib/malloc.h>
1312
13+ #include "private/utils.h"
14+
1415/* List node */
1516typedef struct list_node {
1617 struct list_node * next ;
@@ -26,12 +27,18 @@ typedef struct {
2627
2728static inline list_t * list_create (void )
2829{
29- list_t * list = malloc (sizeof (list_t ));
30- list_node_t * head = malloc (sizeof (list_node_t ));
31- list_node_t * tail = malloc (sizeof (list_node_t ));
30+ list_t * list = malloc (sizeof (* list ));
31+ if (unlikely (!list ))
32+ return NULL ;
33+
34+ list_node_t * head = malloc (sizeof (* head ));
35+ if (unlikely (!head )) {
36+ free (list );
37+ return NULL ;
38+ }
3239
33- if (! list || ! head || ! tail ) { /* cleanup on failure */
34- free ( tail );
40+ list_node_t * tail = malloc ( sizeof ( * tail ));
41+ if ( unlikely (! tail )) {
3542 free (head );
3643 free (list );
3744 return NULL ;
@@ -64,7 +71,7 @@ static inline list_node_t *list_next(const list_node_t *node)
6471static inline list_node_t * list_cnext (const list_t * list ,
6572 const list_node_t * node )
6673{
67- if (!list || !node )
74+ if (unlikely ( !list || !node ) )
6875 return NULL ;
6976 return (node -> next == list -> tail ) ? list -> head -> next : node -> next ;
7077}
@@ -73,17 +80,15 @@ static inline list_node_t *list_cnext(const list_t *list,
7380
7481static inline list_node_t * list_pushback (list_t * list , void * data )
7582{
76- if (!list )
83+ if (unlikely ( !list ) )
7784 return NULL ;
7885
79- list_node_t * node = malloc (sizeof (list_node_t ));
80- if (!node )
86+ list_node_t * node = malloc (sizeof (* node ));
87+ if (unlikely ( !node ) )
8188 return NULL ;
8289
8390 node -> data = data ;
8491 node -> next = list -> tail ;
85- list -> tail -> data = NULL ; /* head and tail sentinels never hold data */
86- list -> head -> data = NULL ;
8792
8893 /* Insert before tail sentinel */
8994 list_node_t * prev = list -> head ;
@@ -97,7 +102,7 @@ static inline list_node_t *list_pushback(list_t *list, void *data)
97102
98103static inline void * list_pop (list_t * list )
99104{
100- if (list_is_empty (list ))
105+ if (unlikely ( list_is_empty (list ) ))
101106 return NULL ;
102107
103108 list_node_t * first = list -> head -> next ;
@@ -112,14 +117,14 @@ static inline void *list_pop(list_t *list)
112117/* Remove a specific node; returns its data */
113118static inline void * list_remove (list_t * list , list_node_t * target )
114119{
115- if (!list || !target || list_is_empty (list ))
120+ if (unlikely ( !list || !target || list_is_empty (list ) ))
116121 return NULL ;
117122
118123 list_node_t * prev = list -> head ;
119124 while (prev -> next != list -> tail && prev -> next != target )
120125 prev = prev -> next ;
121126
122- if (prev -> next != target )
127+ if (unlikely ( prev -> next != target ) )
123128 return NULL ; /* node not found */
124129
125130 prev -> next = target -> next ;
@@ -137,15 +142,16 @@ static inline list_node_t *list_foreach(list_t *list,
137142 void * ),
138143 void * arg )
139144{
140- if (!list || !cb )
145+ if (unlikely ( !list || !cb ) )
141146 return NULL ;
142147
143148 list_node_t * node = list -> head -> next ;
144149 while (node != list -> tail ) {
150+ list_node_t * next = node -> next ; /* Save next before callback */
145151 list_node_t * res = cb (node , arg );
146152 if (res )
147153 return res ;
148- node = node -> next ;
154+ node = next ;
149155 }
150156 return NULL ;
151157}
@@ -154,7 +160,7 @@ static inline list_node_t *list_foreach(list_t *list,
154160
155161static inline void list_clear (list_t * list )
156162{
157- if (!list )
163+ if (unlikely ( !list ) )
158164 return ;
159165 while (!list_is_empty (list ))
160166 list_pop (list );
0 commit comments