From: Junio C Hamano <gitster@pobox.com>
To: Jessica Clarke <jrtc27@jrtc27.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH v2] mem-pool: Don't assume uintmax_t is aligned enough for all types
Date: Sun, 23 Jan 2022 12:17:16 -0800 [thread overview]
Message-ID: <xmqqsfte8awj.fsf@gitster.g> (raw)
In-Reply-To: <20220123152458.72540-1-jrtc27@jrtc27.com> (Jessica Clarke's message of "Sun, 23 Jan 2022 15:24:58 +0000")
Jessica Clarke <jrtc27@jrtc27.com> writes:
> Currently mem_pool_alloc uses sizeof(uintmax_t) as a proxy for what
> should be _Alignof(max_align_t) in C11. On most architectures this is
Lose "Currently", as the present tense describes the status quo, the
shape of the problematic code we have today that wants improvement
by the proposed patch.
> sufficient (though on m68k it is in fact overly strict, since the
> de-facto ABI, which differs from the specified System V ABI, has the
> maximum alignment of all types as 2 bytes), but on CHERI, and thus Arm's
> Morello prototype, it is insufficient for any type that stores a
> pointer, which must be aligned to 128 bits (on 64-bit architectures
> extended with CHERI), whilst uintmax_t is a 64-bit integer.
OK.
> Fix this by introducing our own approximation for max_align_t and a
> means to compute _Alignof it without relying on C11. Currently this
> union only contains uintmax_t and void *, but more types can be added as
> needed.
Nicely described.
> +/*
> + * The inner union is an approximation for C11's max_align_t, and the
> + * struct + offsetof computes _Alignof. This can all just be replaced
> + * with _Alignof(max_align_t) if/when C11 is part of the baseline.
> + *
> + * Add more types to the union if the current set is insufficient.
> + */
> +struct git_max_alignment {
> + char unalign;
> + union {
> + uintmax_t max_align_uintmax;
> + void *max_align_pointer;
> + } aligned;
> +};
> +#define GIT_MAX_ALIGNMENT offsetof(struct git_max_alignment, aligned)
> +
The original computed the alignment requirement for uintmax_t as
sizeof(uintmax_t), not as
offsetof(struct {
char unalign;
union { uintmax_t i; } aligned;
}, aligned)
because if you have an array of a type, each element of it must be
aligned appropriately already for that type, without the unalignment
the outer struct enforces. I wonder if your complex offsetof is
equivalent to sizeof(union { uintmax_t u; void *p; })?
IOW, in this struct:
struct max_alignment_helper {
char unalign;
union {
uintmax_t uintmax_t_unused;
void *pointer_unused;
} u[2];
} s;
both s.u[0] and s.u[1] must be properly aligned, so wouldn't the
alignment requirement for the union type, which can be used to hold
a single value of either uintmax_t or a poinhter, be the distance
between these two array elements, i.e. sizeof(s.u[0])?
To put it differently in yet another way, wouldn't it simplify down
to this?
union max_alignment_helper {
uintmax_t uintmax_t_unused;
void *pointer_unused;
};
#define GIT_MAX_ALIGNMENT sizeof(union max_alignment_helper);
I am not saying that the "a forcibly unaligned union in a struct" is
a bad/wrong way to express what you want to achieve. I just do not
know if there is a reason to choose it over a seemingly simpler
sizeof(that union) without the outer struct and unalign member.
Other than that, looks OK to me. Especially the parts that use the
macro look correctly converted.
Thanks.
> @@ -69,9 +85,9 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
> struct mp_block *p = NULL;
> void *r;
>
> - /* round up to a 'uintmax_t' alignment */
> - if (len & (sizeof(uintmax_t) - 1))
> - len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
> + /* round up to a 'GIT_MAX_ALIGNMENT' alignment */
> + if (len & (GIT_MAX_ALIGNMENT - 1))
> + len += GIT_MAX_ALIGNMENT - (len & (GIT_MAX_ALIGNMENT - 1));
>
> if (pool->mp_block &&
> pool->mp_block->end - pool->mp_block->next_free >= len)
> /*
> * Allocate a new mp_block and insert it after the block specified in
> * `insert_after`. If `insert_after` is NULL, then insert block at the
> @@ -69,9 +85,9 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
> struct mp_block *p = NULL;
> void *r;
>
> - /* round up to a 'uintmax_t' alignment */
> - if (len & (sizeof(uintmax_t) - 1))
> - len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
> + /* round up to a 'GIT_MAX_ALIGNMENT' alignment */
> + if (len & (GIT_MAX_ALIGNMENT - 1))
> + len += GIT_MAX_ALIGNMENT - (len & (GIT_MAX_ALIGNMENT - 1));
>
> if (pool->mp_block &&
> pool->mp_block->end - pool->mp_block->next_free >= len)
next prev parent reply other threads:[~2022-01-23 20:17 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-05 13:23 [PATCH] Properly align memory allocations and temporary buffers Jessica Clarke
2022-01-06 21:46 ` Taylor Blau
2022-01-06 21:56 ` Jessica Clarke
2022-01-06 22:27 ` Junio C Hamano
2022-01-06 22:56 ` Jessica Clarke
2022-01-07 0:10 ` Junio C Hamano
2022-01-07 0:22 ` Jessica Clarke
2022-01-07 0:31 ` brian m. carlson
2022-01-07 0:39 ` Jessica Clarke
2022-01-07 1:43 ` brian m. carlson
2022-01-07 2:08 ` Jessica Clarke
2022-01-07 2:11 ` Jessica Clarke
2022-01-07 19:30 ` Junio C Hamano
2022-01-07 19:33 ` Jessica Clarke
2022-01-07 20:56 ` René Scharfe
2022-01-07 21:30 ` Junio C Hamano
2022-01-07 23:30 ` René Scharfe
2022-01-08 0:18 ` Elijah Newren
2022-01-06 23:22 ` brian m. carlson
2022-01-06 23:31 ` Jessica Clarke
2022-01-07 14:57 ` Philip Oakley
2022-01-07 16:08 ` René Scharfe
2022-01-07 16:21 ` Jessica Clarke
2022-01-12 13:58 ` Jessica Clarke
2022-01-12 15:47 ` René Scharfe
2022-01-12 15:49 ` Jessica Clarke
2022-01-23 15:24 ` [PATCH v2] mem-pool: Don't assume uintmax_t is aligned enough for all types Jessica Clarke
2022-01-23 20:17 ` Junio C Hamano [this message]
2022-01-23 20:23 ` Jessica Clarke
2022-01-23 20:28 ` Junio C Hamano
2022-01-23 20:33 ` [PATCH v3] " Jessica Clarke
2022-01-24 17:11 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqsfte8awj.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=jrtc27@jrtc27.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.