src/ucx/linked_list.c

changeset 645
0c85c4cd0dd8
parent 621
956c03c25edd
--- a/src/ucx/linked_list.c	Sat Nov 29 19:03:52 2025 +0100
+++ b/src/ucx/linked_list.c	Sun Nov 30 18:25:55 2025 +0100
@@ -31,6 +31,15 @@
 #include <string.h>
 #include <assert.h>
 
+#if __STDC_VERSION__ < 202311L
+// we cannot simply include stdalign.h
+// because Solaris is not entirely C11 complaint
+#ifndef __alignof_is_defined
+#define alignof _Alignof
+#define __alignof_is_defined 1
+#endif
+#endif
+
 // LOW LEVEL LINKED LIST FUNCTIONS
 
 #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off)))
@@ -516,7 +525,7 @@
     void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE];
     void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
                     cxMallocDefault(sizeof(void *) * length) : sbo;
-    if (sorted == NULL) abort();
+    if (sorted == NULL) abort(); // LCOV_EXCL_LINE
     void *rc, *lc;
 
     lc = ls;
@@ -692,8 +701,13 @@
 }
 
 static void *cx_ll_malloc_node(const cx_linked_list *list) {
-    return cxZalloc(list->base.collection.allocator,
-                    list->loc_data + list->base.collection.elem_size + list->extra_data_len);
+    size_t n;
+    if (list->extra_data_len == 0) {
+        n = list->loc_data + list->base.collection.elem_size;
+    } else {
+        n = list->loc_extra + list->extra_data_len;
+    }
+    return cxZalloc(list->base.collection.allocator, n);
 }
 
 static int cx_ll_insert_at(
@@ -1215,7 +1229,7 @@
         return result;
     } else {
         if (cx_ll_insert_element(list, list->collection.size, elem) == NULL) {
-            return 1;
+            return 1; // LCOV_EXCL_LINE
         }
         iter->elem_count++;
         iter->index = list->collection.size;
@@ -1252,6 +1266,7 @@
         cx_ll_sort,
         cx_ll_compare,
         cx_ll_reverse,
+        NULL, // no overallocation supported
         cx_ll_iterator,
 };
 
@@ -1266,12 +1281,22 @@
 
     cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list));
     if (list == NULL) return NULL;
-    list->extra_data_len = 0;
     list->loc_prev = 0;
     list->loc_next = sizeof(void*);
     list->loc_data = sizeof(void*)*2;
+    list->loc_extra = -1;
+    list->extra_data_len = 0;
     cx_list_init((CxList*)list, &cx_linked_list_class,
             allocator, comparator, elem_size);
 
     return (CxList *) list;
 }
+
+void cx_linked_list_extra_data(cx_linked_list *list, size_t len) {
+    list->extra_data_len = len;
+
+    off_t loc_extra = list->loc_data + list->base.collection.elem_size;
+    size_t alignment = alignof(void*);
+    size_t padding = alignment - (loc_extra % alignment);
+    list->loc_extra = loc_extra + padding;
+}

mercurial