bug-gnulib
[Top][All Lists]
Advanced

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

flexmember: Make it easier to use


From: Bruno Haible
Subject: flexmember: Make it easier to use
Date: Sat, 27 May 2023 00:19:31 +0200

The most natural use of the 'flexmember' module is to allocate memory for a

  struct { <some_fields>; <array_elt_type> member [FLEXIBLE_ARRAY_MEMBER]; }

I was surprised to see that for this use, one has to pass
  <number_of_array_elements> * sizeof (<array_elt_type>)
as third argument to FLEXSIZEOF, not merely
  <number_of_array_elements>.

I made the mistake of not doing the multiplication (in some new code).
And Marc, in the 'hamt' module, make the mistake of passing
sizeof (Hamt_entry) rather than sizeof (Hamt_entry *).

So, for better usability, it's good to have a macro that acts like FLEXSIZEOF,
except that it expects an element count instead of a byte count as third
argument.


2023-05-26  Bruno Haible  <bruno@clisp.org>

        flexmember: Make it easier to use.
        * lib/flexmember.h (FLEXNSIZEOF): New macro.
        * lib/hamt.c (alloc_bucket, alloc_subtrie): Fix FLEXSIZEOF invocation.
        Use FLEXNSIZEOF instead of FLEXSIZEOF.
        * lib/ssfmalloc.h (init_small_block_page_pool): Use FLEXNSIZEOF instead
        of FLEXSIZEOF.

diff --git a/lib/flexmember.h b/lib/flexmember.h
index 8c5915ecf9..8df4419539 100644
--- a/lib/flexmember.h
+++ b/lib/flexmember.h
@@ -43,7 +43,7 @@
    followed by N bytes of other data.  The result is suitable as an
    argument to malloc.  For example:
 
-     struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; };
+     struct s { int a; char d[FLEXIBLE_ARRAY_MEMBER]; };
      struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char)));
 
    FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N),
@@ -63,3 +63,14 @@
 #define FLEXSIZEOF(type, member, n) \
    ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \
     & ~ (FLEXALIGNOF (type) - 1))
+
+/* Yield a properly aligned upper bound on the size of a struct of
+   type TYPE with a flexible array member named MEMBER that has N
+   elements.  The result is suitable as an argument to malloc.
+   For example:
+
+     struct s { int a; double d[FLEXIBLE_ARRAY_MEMBER]; };
+     struct s *p = malloc (FLEXNSIZEOF (struct s, d, n));
+ */
+#define FLEXNSIZEOF(type, member, n) \
+  FLEXSIZEOF (type, member, (n) * sizeof (((type *) 0)->member[0]))
diff --git a/lib/hamt.c b/lib/hamt.c
index 8cbca387f0..6f39b77c2f 100644
--- a/lib/hamt.c
+++ b/lib/hamt.c
@@ -214,8 +214,7 @@ static struct bucket *
 alloc_bucket (size_t elt_count)
 {
   struct bucket *bucket
-    = xmalloc (FLEXSIZEOF (struct bucket, elts,
-                           sizeof (Hamt_entry) * elt_count));
+    = xmalloc (FLEXNSIZEOF (struct bucket, elts, elt_count));
   init_ref_counter (&bucket->ref_counter, bucket_entry);
   bucket->elt_count = elt_count;
   return bucket;
@@ -251,8 +250,7 @@ static struct subtrie *
 alloc_subtrie (int node_count)
 {
   struct subtrie *subtrie
-    = xmalloc (FLEXSIZEOF (struct subtrie, nodes,
-                           sizeof (Hamt_entry) * node_count));
+    = xmalloc (FLEXNSIZEOF (struct subtrie, nodes, node_count));
   init_ref_counter (&subtrie->ref_count, subtrie_entry);
   return subtrie;
 }
diff --git a/lib/ssfmalloc.h b/lib/ssfmalloc.h
index 87f44014e4..5dd69c8199 100644
--- a/lib/ssfmalloc.h
+++ b/lib/ssfmalloc.h
@@ -332,8 +332,8 @@ static unsigned int small_block_page_num_bitmap_words;
 struct small_page_header
 {
   struct dissected_page_header common;
-  /* Two bitmaps, each with small_block_page_num_bitmap_words. In each a bit
-     represents ALIGNMENT bytes.
+  /* Two bitmaps, each with small_block_page_num_bitmap_words words. In each
+     a bit represents ALIGNMENT bytes.
        - available_bitmap: bit set means available, bit clear means allocated.
        - blockend_bitmap: bit set means the an allocated block ends here.  */
   uint32_t bitmap_words[FLEXIBLE_ARRAY_MEMBER];
@@ -365,8 +365,8 @@ init_small_block_page_pool (struct page_pool *pool)
     {
       num_bitmap_words = (num_bits + 32 - 1) / 32;
       blocks_start =
-        (FLEXSIZEOF (struct small_page_header, bitmap_words,
-                     2 * num_bitmap_words * sizeof (uint32_t))
+        (FLEXNSIZEOF (struct small_page_header, bitmap_words,
+                      2 * num_bitmap_words)
          + ALIGNMENT - 1) & -ALIGNMENT;
       unsigned int num_bits_r = (unsigned int) (PAGESIZE - blocks_start) / 
ALIGNMENT;
       if (num_bits_r >= num_bits)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]