Age | Commit message (Collapse) | Author |
|
fork()
|
|
In order to improve energy consumption we should minimize our wake-ups
when handling timers. Hence, for each timer take an accuracy value and
schedule the actual wake-up time somewhere between the specified time
and the specified timer plus the accuracy.
The specified time of timer event sources hence becomes the time the
handler is called the *earliest*, and the specified time plus the accuracy
the time by which it is called the *latest*, leaving the library the
freedom to schedule the wake-up somewhere inbetween.
If the accuracy is specified as 0 the default of 250ms will be used.
When scheduling timeouts we will now try to elapse them at the same
point within each second, across the entire system. We do this by using
a fixed perturbation value keyed off the boot id. If this point within a
second is not in the acceptable range, we try again with a fixed time
within each 250ms time step. If that doesn't work either, we wake up at
the last possible time.
|
|
Testing for y > x is the same as testing for x < y.
|
|
So far we tried to use epoll directly wherever we needed an event loop.
However, that has various shortcomings, such as the inability to handle
larger amounts of timers (since each timerfd costs one fd, which is a
very limited resource, usually bounded to 1024), and inability to do
priorisation between multiple queued events.
Let's add a minimal event loop API around epoll that is suitable for
implementation of our own daemons and maybe one day can become public
API for those who desire it.
This loop is part of libsystemd-bus, but may be used independently of
it.
|
|
|
|
|
|
|
|
|
|
objects on the bus
This adds a lightweight scheme how to define interfaces in static fixed
arrays which then can be easily registered on a bus connection. This
makes it much easier to write bus services.
This automatically handles implementation of the Properties,
ObjectManager, and Introspection bus interfaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- for now, comment out munmap() check to enable memfd passing
- print tab-separated values and header
- add memcpy() to fill the memfd, to produce real-world results
$ ./test-bus-kernel-benchmark
SIZE COPY MEMFD
4194304 370 370
2097152 810 810
1048576 2130 2130
524288 4090 4090
262144 7080 7080
131072 11380 11380
65536 17140 17140
98304 13930 13930
114688 12890 12890
122880 12350 12350
126976 12150 12150
129024 12170 12170
130048 12040 12040
130560 12080 12080
130816 12010 12010
130944 12020 12020
131008 12040 12040
131040 12050 12050
131056 12010 12010
131064 12060 12060
131068 12040 12040
131070 11310 11310
131069 11420 11420
Copying/memfd are equally fast at 131068 bytes
$ ./test-bus-kernel-benchmark chart
SIZE COPY MEMFD
1 35570 23690
2 36470 23680
4 36160 23520
8 36600 22220
16 33900 20830
32 33990 21360
64 33480 21280
128 34050 20910
256 32950 21750
512 34730 21900
1024 33810 22890
2048 36280 23110
4096 30790 21610
8192 29380 21100
16384 26880 19820
32768 22510 17980
65536 17270 15180
131072 11400 11420
262144 7140 8270
524288 4090 5050
1048576 2110 2780
2097152 800 1140
4194304 350 580
|
|
finishes more quickly
To get useful results you should however specify a much longer time on
the command line.
|
|
transaction
This way the measurements are not skewed by twoo short total measurement
times, and results become stabler.
|
|
|
|
|
|
|
|
remainder
|
|
|
|
|
|
|
|
|
|
|
|
Yay! Filtering using kernel bloom filter matches works now! Yippieh!
|
|
|
|
|
|
We want to allow clients to process an sd_bus_message on a different
thread than it was received on. Since unreffing a bus message might
readd some of its memfds to the memfd cache add some minimal locking
around the cache.
|
|
fork()
|
|
|
|
We need this since we might need to invoke the release ioctl for
messages. Since we don't want to add any locking for that we simply keep
a reference to the bus and then rely that the fd stays valid all the
time.
|
|
This is preparation to allow sd_bus_message obejcts to be processed in a
different thread from their originating sd_bus object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This allows us to guarantee that the first payload_vec we pass to the
kernel for each message is guaranteed to include the full header and all
its field.
|
|
|
|
|
|
|
|
|
|
than a single one
|