diff options
author | Alan Jenkins <alan-jenkins@tuffmail.co.uk> | 2009-05-21 22:22:37 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@vrfy.org> | 2009-05-21 22:22:37 +0200 |
commit | f503f6b22fa54d1a65156a51d8b3311190c73ae5 (patch) | |
tree | 5003144371ce463fe5ba2387b9777cd8cddd24ad /udev/udevadm-settle.c | |
parent | f9b3f88f71f5bdfb18aa4bfba00d72fa41fdf286 (diff) |
udevd: implement a more efficient queue file format
Directory lookups show up in profiling. The queue files are responsible
for a large proportion of file-related system calls in udev coldplug.
Instead of creating a file for each event, append their details to a
log file. The file is periodically rebuilt (garbage-collected) to
prevent it from growing indefinitely.
This single queue file replaces both the queue directory and the
uevent_seqnum file. On desktop systems the file tends not to grow
beyond one page. So it should also save a small amount of memory in
tmpfs.
Tests on a running EeePC indicate average savings of 5% *udevd* cpu time
as measured by oprofile. __link_path_walk is reduced from 1.5% to
1.3%. It is not completely clear where the rest of the gains come from.
In tests running ~400 events, the queue file is rebuilt about 5 times.
Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Diffstat (limited to 'udev/udevadm-settle.c')
-rw-r--r-- | udev/udevadm-settle.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/udev/udevadm-settle.c b/udev/udevadm-settle.c index 52d9c0b244..f1052aa148 100644 --- a/udev/udevadm-settle.c +++ b/udev/udevadm-settle.c @@ -173,24 +173,16 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[]) } while (!is_timeout) { - /* exit if queue is empty */ - if (udev_queue_get_queue_is_empty(udev_queue)) - break; - - /* if asked for, wait for a specific sequence of events */ if (start > 0) { - unsigned long long seq; - int finished; - - finished = 0; - for (seq = start; seq <= end; seq++) { - finished = udev_queue_get_seqnum_is_finished(udev_queue, seq); - if (!finished) - break; - } - if (finished) + /* if asked for, wait for a specific sequence of events */ + if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) + break; + } else { + /* exit if queue is empty */ + if (udev_queue_get_queue_is_empty(udev_queue)) break; } + usleep(1000 * 1000 / LOOP_PER_SECOND); } |