[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)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- flexmember: Make it easier to use,
Bruno Haible <=