In sd_event_source.child, we have 5 bools. If we make them each take one byte,
the structure size increases. So let's do that for the three of them, and leave
the other two (less frequently used) squished into the last byte. This allows
more efficient code to be generated, without changing the size of the struct:
$ diff -u <(objdump -S build/src/shared/libsystemd-shared-258.so.0|awk '/^static void source_io_unregister/,/^\}/') \
<(objdump -S build/src/shared/libsystemd-shared-258.so|awk '/^static void source_io_unregister/,/^\}/')
s->io.registered = false;
- 34d46f: 48 8b 45 d8 mov -0x28(%rbp),%rax
- 34d473: 0f b6 90 a4 00 00 00 movzbl 0xa4(%rax),%edx
- 34d47a: 83 e2 fe and $0xfffffffe,%edx
- 34d47d: 88 90 a4 00 00 00 mov %dl,0xa4(%rax)
- 34d483: eb 04 jmp 34d489 <source_io_unregister+0x1ca>
+ 34bffe: 48 8b 45 d8 mov -0x28(%rbp),%rax
+ 34c002: c6 80 a4 00 00 00 00 movb $0x0,0xa4(%rax)
+ 34c009: eb 04 jmp 34c00f <source_io_unregister+0x1be>
return;
pid_t pid;
int options;
int pidfd;
- bool registered:1; /* whether the pidfd is registered in the epoll */
+ /* We have five bools, and we want to fit them into 4 bytes so the whole struct
+ * remains 32 bytes. Thus, use bitfields for two of them and single bytes for the
+ * other three. */
+ bool registered; /* whether the pidfd is registered in the epoll */
bool pidfd_owned:1; /* close pidfd when event source is freed */
bool process_owned:1; /* kill+reap process when event source is freed */
- bool exited:1; /* true if process exited (i.e. if there's value in SIGKILLing it if we want to get rid of it) */
- bool waited:1; /* true if process was waited for (i.e. if there's value in waitid(P_PID)'ing it if we want to get rid of it) */
+ bool exited; /* true if process exited (i.e. if there's value in SIGKILLing it if
+ * we want to get rid of it) */
+ bool waited; /* true if process was waited for (i.e. if there's value in
+ * waitid(P_PID)'ing it if we want to get rid of it) */
} child;
struct {
sd_event_handler_t callback;