]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-event: drop some bitfield specifiers from struct sd_event_source
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 8 Jun 2025 11:21:28 +0000 (13:21 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 3 Jul 2025 14:17:42 +0000 (16:17 +0200)
This does not change the size of the structure, because the size is determined
by .child, which has a 128-byte siginfo_t field. But by dropping the specifiers
we let the compiler generate code that operates on full bytes instead of having
to play with bitmasks, see second diff below.

Also move the bools in .memory_pressure into a gap to save a few bytes on
initialization.

$ diff -U100 <(pahole build/src/shared/libsystemd-shared-258.so.0 | awk '/struct sd_event_source/,/^}/') \
             <(pahole build/src/shared/libsystemd-shared-258.so | awk '/struct sd_event_source/,/^}/')
--- /proc/self/fd/11 2025-06-08 13:16:55.614738334 +0200
+++ /proc/self/fd/12 2025-06-08 13:16:55.615738386 +0200
@@ -1,109 +1,109 @@
 struct sd_event_source {
  WakeupType                 wakeup;               /*     0     4 */
  unsigned int               n_ref;                /*     4     4 */
  sd_event *                 event;                /*     8     8 */
  void *                     userdata;             /*    16     8 */
  sd_event_handler_t         prepare;              /*    24     8 */
  char *                     description;          /*    32     8 */
  EventSourceType            type;                 /*    40     4 */
        signed int                 enabled:3;            /*    44: 0  4 */
  _Bool                      pending:1;            /*    44: 3  1 */
  _Bool                      dispatching:1;        /*    44: 4  1 */
  _Bool                      floating:1;           /*    44: 5  1 */
  _Bool                      exit_on_failure:1;    /*    44: 6  1 */
  _Bool                      ratelimited:1;        /*    44: 7  1 */

  /* XXX 24 bits hole, try to pack */

  int64_t                    priority;             /*    48     8 */
  unsigned int               pending_index;        /*    56     4 */
  unsigned int               prepare_index;        /*    60     4 */
  /* --- cacheline 1 boundary (64 bytes) --- */
  uint64_t                   pending_iteration;    /*    64     8 */
  uint64_t                   prepare_iteration;    /*    72     8 */
  sd_event_destroy_t         destroy_callback;     /*    80     8 */
  sd_event_handler_t         ratelimit_expire_callback; /*    88     8 */
  sd_event_source *          sources_next;         /*    96     8 */
  sd_event_source *          sources_prev;         /*   104     8 */
  RateLimit                  rate_limit;           /*   112    24 */
  /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
  unsigned int               earliest_index;       /*   136     4 */
  unsigned int               latest_index;         /*   140     4 */
  union {
  struct {
  sd_event_io_handler_t callback;  /*   144     8 */
  int        fd;                   /*   152     4 */
  uint32_t   events;               /*   156     4 */
  uint32_t   revents;              /*   160     4 */
- _Bool      registered:1;         /*   164: 0  1 */
- _Bool      owned:1;              /*   164: 1  1 */
+ _Bool      registered;           /*   164     1 */
+ _Bool      owned;                /*   165     1 */
  } io;                                    /*   144    24 */
  struct {
  sd_event_time_handler_t callback; /*   144     8 */
  usec_t     next;                 /*   152     8 */
  usec_t     accuracy;             /*   160     8 */
  } time;                                  /*   144    24 */
  struct {
  sd_event_signal_handler_t callback; /*   144     8 */
  struct signalfd_siginfo siginfo; /*   152   128 */
  /* --- cacheline 4 boundary (256 bytes) was 24 bytes ago --- */
  int        sig;                  /*   280     4 */
  _Bool      unblock;              /*   284     1 */
  } signal;                                /*   144   144 */
  struct {
  sd_event_child_handler_t callback; /*   144     8 */
  siginfo_t  siginfo;              /*   152   128 */
  /* --- cacheline 4 boundary (256 bytes) was 24 bytes ago --- */
  pid_t      pid;                  /*   280     4 */
  int        options;              /*   284     4 */
  int        pidfd;                /*   288     4 */
  _Bool      registered:1;         /*   292: 0  1 */
  _Bool      pidfd_owned:1;        /*   292: 1  1 */
  _Bool      process_owned:1;      /*   292: 2  1 */
  _Bool      exited:1;             /*   292: 3  1 */
  _Bool      waited:1;             /*   292: 4  1 */
  } child;                                 /*   144   152 */
  struct {
  sd_event_handler_t callback;     /*   144     8 */
  } defer;                                 /*   144     8 */
  struct {
  sd_event_handler_t callback;     /*   144     8 */
  } post;                                  /*   144     8 */
  struct {
  sd_event_handler_t callback;     /*   144     8 */
  unsigned int prioq_index;        /*   152     4 */
  } exit;                                  /*   144    16 */
  struct {
  sd_event_inotify_handler_t callback; /*   144     8 */
  uint32_t   mask;                 /*   152     4 */

  /* XXX 4 bytes hole, try to pack */

  struct inode_data * inode_data;  /*   160     8 */
  sd_event_source * by_inode_data_next; /*   168     8 */
  sd_event_source * by_inode_data_prev; /*   176     8 */
  } inotify;                               /*   144    40 */
  struct {
  int        fd;                   /*   144     4 */
+ _Bool      registered;           /*   148     1 */
+ _Bool      locked;               /*   149     1 */
+ _Bool      in_write_list;        /*   150     1 */

- /* XXX 4 bytes hole, try to pack */
+ /* XXX 1 byte hole, try to pack */

  sd_event_handler_t callback;     /*   152     8 */
  void *     write_buffer;         /*   160     8 */
  size_t     write_buffer_size;    /*   168     8 */
  uint32_t   events;               /*   176     4 */
  uint32_t   revents;              /*   180     4 */
  sd_event_source * write_list_next; /*   184     8 */
  /* --- cacheline 3 boundary (192 bytes) --- */
  sd_event_source * write_list_prev; /*   192     8 */
- _Bool      registered:1;         /*   200: 0  1 */
- _Bool      locked:1;             /*   200: 1  1 */
- _Bool      in_write_list:1;      /*   200: 2  1 */
- } memory_pressure;                       /*   144    64 */
+ } memory_pressure;                       /*   144    56 */
  };                                               /*   144   152 */

  /* size: 296, cachelines: 5, members: 26 */
  /* sum members: 292 */
  /* sum bitfield members: 8 bits, bit holes: 1, sum bit holes: 24 bits */
  /* last cacheline: 40 bytes */
 };

Example diff in assembly:

$ diff -u <(objdump -S build/src/shared/libsystemd-shared-258.so.0|awk '/^static void event_source_time_prioq_reshuffle/,/^\}/') \
          <(objdump -S build/src/shared/libsystemd-shared-258.so|awk '/^static void event_source_time_prioq_reshuffle/,/^\}/')

         d->needs_rearm = true;
-  34d80e:      48 8b 45 f8             mov    -0x8(%rbp),%rax
-  34d812:      0f b6 50 20             movzbl 0x20(%rax),%edx
-  34d816:      83 ca 01                or     $0x1,%edx
-  34d819:      88 50 20                mov    %dl,0x20(%rax)
-  34d81c:      eb 01                   jmp    34d81f <event_source_time_prioq_reshuffle+0x12c>
+  34d7c3:      48 8b 45 f8             mov    -0x8(%rbp),%rax
+  34d7c7:      c6 40 20 01             movb   $0x1,0x20(%rax)
+  34d7cb:      eb 01                   jmp    34d7ce <event_source_time_prioq_reshuffle+0x126>
                 return; /* no-op for an event source which is neither a timer nor ratelimited. */
-  34d81e:      90                      nop
+  34d7cd:      90                      nop

src/libsystemd/sd-event/event-source.h

index 5fef3b1ac9738551233dace529c26f4e85f6e6bb..385779df2c62c26f5bef951209368324fd8c532e 100644 (file)
@@ -87,8 +87,8 @@ struct sd_event_source {
                         int fd;
                         uint32_t events;
                         uint32_t revents;
-                        bool registered:1;
-                        bool owned:1;
+                        bool registered;
+                        bool owned;
                 } io;
                 struct {
                         sd_event_time_handler_t callback;
@@ -130,14 +130,14 @@ struct sd_event_source {
                 } inotify;
                 struct {
                         int fd;
+                        bool registered;
+                        bool locked;
+                        bool in_write_list;
                         sd_event_handler_t callback;
                         void *write_buffer;
                         size_t write_buffer_size;
                         uint32_t events, revents;
                         LIST_FIELDS(sd_event_source, write_list);
-                        bool registered:1;
-                        bool locked:1;
-                        bool in_write_list:1;
                 } memory_pressure;
         };
 };
@@ -157,7 +157,7 @@ struct clock_data {
         Prioq *latest;
         usec_t next;
 
-        bool needs_rearm:1;
+        bool needs_rearm;
 };
 
 struct signal_data {