1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-06 17:18:12 +03:00

Merge pull request #26438 from poettering/event-source-shorten

sd-event: reduce memory use of sd_event_source objects
This commit is contained in:
Lennart Poettering 2023-02-17 12:46:55 +01:00 committed by GitHub
commit 9857dc1117
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 9 deletions

View File

@ -248,6 +248,7 @@ static inline int __coverity_check_and_return__(int condition) {
#define char_array_0(x) x[sizeof(x)-1] = 0;
#define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member)
#define endoffsetof_field(struct_type, member) (offsetof(struct_type, member) + sizeof_field(struct_type, member))
/* Returns the number of chars needed to format variables of the specified type as a decimal string. Adds in
* extra space for a negative '-' prefix for signed types. Includes space for the trailing NUL. */

View File

@ -1075,22 +1075,46 @@ static int source_set_pending(sd_event_source *s, bool b) {
}
static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
/* Let's allocate exactly what we need. Note that the difference of the smallest event source
* structure to the largest is 144 bytes on x86-64 at the time of writing, i.e. more than two cache
* lines. */
static const size_t size_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
[SOURCE_IO] = endoffsetof_field(sd_event_source, io),
[SOURCE_TIME_REALTIME] = endoffsetof_field(sd_event_source, time),
[SOURCE_TIME_BOOTTIME] = endoffsetof_field(sd_event_source, time),
[SOURCE_TIME_MONOTONIC] = endoffsetof_field(sd_event_source, time),
[SOURCE_TIME_REALTIME_ALARM] = endoffsetof_field(sd_event_source, time),
[SOURCE_TIME_BOOTTIME_ALARM] = endoffsetof_field(sd_event_source, time),
[SOURCE_SIGNAL] = endoffsetof_field(sd_event_source, signal),
[SOURCE_CHILD] = endoffsetof_field(sd_event_source, child),
[SOURCE_DEFER] = endoffsetof_field(sd_event_source, defer),
[SOURCE_POST] = endoffsetof_field(sd_event_source, post),
[SOURCE_EXIT] = endoffsetof_field(sd_event_source, exit),
[SOURCE_INOTIFY] = endoffsetof_field(sd_event_source, inotify),
};
sd_event_source *s;
assert(e);
assert(type >= 0);
assert(type < _SOURCE_EVENT_SOURCE_TYPE_MAX);
assert(size_table[type] > 0);
s = new(sd_event_source, 1);
/* We use expand_to_usable() here to tell gcc that it should consider this an object of the full
* size, even if we only allocate the initial part we need. */
s = expand_to_usable(malloc0(size_table[type]), sizeof(sd_event_source));
if (!s)
return NULL;
*s = (struct sd_event_source) {
.n_ref = 1,
.event = e,
.floating = floating,
.type = type,
.pending_index = PRIOQ_IDX_NULL,
.prepare_index = PRIOQ_IDX_NULL,
};
/* Note: we cannot use compound initialization here, because sizeof(sd_event_source) is likely larger
* than what we allocated here. */
s->n_ref = 1;
s->event = e;
s->floating = floating;
s->type = type;
s->pending_index = PRIOQ_IDX_NULL;
s->prepare_index = PRIOQ_IDX_NULL;
if (!floating)
sd_event_ref(e);