replace fgets() with mmap() and introduce udev_lib.[hc]
PATCH 1/1 replace fgets() with mmap() and introduce udev_lib.[hc]
Here we replace the various fgets() with a mmap() call for the config file reading, due to the reported performance problems with klibc.
Thanks to Patrick's testing, it makes a very small, close to nothing speed gain for libc users, but a 6 times speed increase for klibc users with a 1000 line config file.
I've created a udev_lib.[hc] for this and also moved all the generic stuff from udev.h in there and uninlined the functions.
thanks,
Kay
Makefile +5 -3
@@ -201,7 +201,8 @@ $(PWD)/libsysfs/sysfs_utils.o \ $(PWD)/libsysfs/dlist.o -OBJS = udev_config.o \ +OBJS = udev_lib.o \ + udev_config.o \ udev-add.o \ udev-remove.o \ udevdb.o \
@@ -211,6 +212,7 @@ $(TDB) HEADERS = udev.h \ + udev_lib.h \ namedev.h \ udev_version.h \ udev_dbus.h \
@@ -279,7 +281,7 @@ $(STRIPCMD) $@ $(INFO): $(INFO).o $(OBJS) $(HEADERS) $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(DAEMON): $(DAEMON).o udevd.h $(LIBC)
@@ -287,7 +289,7 @@ $(STRIPCMD) $@ $(SENDER): $(SENDER).o udevd.h $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(STARTER): $(STARTER).o $(HEADERS) $(LIBC)
klibc_fixups.c +22 -8
@@ -28,6 +28,7 @@#include <fcntl.h> #include <sys/types.h> +#include "udev.h" #include "klibc_fixups.h" #include "logging.h"
@@ -40,22 +41,35 @@static unsigned long get_id_by_name (const char *uname,const char *dbfile) {unsigned long id =-1 ; -FILE *file; -char buf[255 ]; +char line[255 ]; +char *buf; +size_t bufsize; +size_t cur; +size_t count;char *pos;char *name;char *idstr;char *tail; - file =fopen (dbfile,"r" ); -if (file ==NULL ) { -dbg ("unable to open file '%s'" , dbfile); +if (file_map (dbfile, &buf, &bufsize) ==0 ) { +dbg ("reading '%s' as db file" , dbfile); + }else { +dbg ("can't open '%s' as db file" , dbfile);return -1 ; } +/* loop through the whole file */ + + cur =0 ;while (1 ) { - pos =fgets (buf,sizeof (buf), file); -if (pos ==NULL ) + count =buf_get_line (buf, bufsize, cur); + +strncpy (line, buf + cur, count); + line[count] ='\0' ; + pos = line; + + cur += count+1 ; +if (cur > bufsize)break ;/* get name */
@@ -82,7 +96,7 @@ } } -fclose (file); +file_unmap (buf, bufsize);return id; }
namedev.c +1 -0
@@ -36,6 +36,7 @@#include "libsysfs/sysfs/libsysfs.h" #include "list.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "namedev.h"
namedev_parse.c +37 -19
114 lines not on this page · raw message
udev-add.c +1 -0
@@ -37,6 +37,7 @@#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "udev_selinux.h"
udev-remove.c +1 -0
@@ -29,6 +29,7 @@#include <errno.h> #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "logging.h"
udev.c +4 -2
@@ -20,15 +20,17 @@* */ +#include <stdio.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> -#include <stdio.h> -#include <errno.h> #include <ctype.h> +#include <errno.h> #include <signal.h> #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "logging.h"
udev.h +11 -95
123 lines not on this page · raw message
udev_config.c +21 -11
@@ -34,6 +34,7 @@#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "namedev.h"
@@ -131,12 +132,14 @@char *temp;char *variable;char *value; -FILE *fd; -int lineno =0 ; +char *buf; +size_t bufsize; +size_t cur; +size_t count; +int lineno;int retval =0 ; - - fd =fopen (udev_config_filename,"r" ); -if (fd !=NULL ) { + +if (file_map (udev_config_filename, &buf, &bufsize) ==0 ) {dbg ("reading '%s' as config file" , udev_config_filename); }else {dbg ("can't open '%s' as config file" , udev_config_filename);
@@ -144,13 +147,20 @@ }/* loop through the whole file */ + lineno =0 ; + cur =0 ;while (1 ) { -/* get a line */ - temp =fgets (line,sizeof (line), fd); -if (temp ==NULL ) - goto exit; + count =buf_get_line (buf, bufsize, cur); + +strncpy (line, buf + cur, count); + line[count] ='\0' ; + temp = line; lineno++; + cur += count+1 ; +if (cur > bufsize) +break ; +dbg_parse ("read '%s'" , temp);/* eat the whitespace at the beginning of the line */
@@ -182,8 +192,8 @@ }dbg_parse ("%s:%d:%Zd: error parsing '%s'" , udev_config_filename, lineno, temp - line, temp); -exit: -fclose (fd); + +file_unmap (buf, bufsize);return retval; }
udev_lib.c new file +111 -0
111 lines not on this page · raw message
udev_lib.h new file +78 -0
78 lines not on this page · raw message
udevd.c +1 -0
@@ -36,6 +36,7 @@#include "list.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udevd.h" #include "logging.h"
udevdb.c +4 -5
@@ -1,5 +1,5 @@/* -* udevdb.c +* udevdb.c - udev database library * * Userspace devfs *
@@ -21,13 +21,11 @@* */ -/* -* udev database library -*/ #define _KLIBC_HAS_ARCH_SIG_ATOMIC_T#include <stdlib.h> #include <stdio.h> #include <string.h> +#include <stddef.h> #include <fcntl.h> #include <string.h> #include <sys/stat.h>
@@ -35,8 +33,9 @@#include <signal.h> #include "libsysfs/sysfs/libsysfs.h" -#include "udev_version.h" #include "udev.h" +#include "udev_lib.h" +#include "udev_version.h" #include "logging.h" #include "namedev.h" #include "udevdb.h"
udevinfo.c +1 -0
@@ -30,6 +30,7 @@#include "libsysfs/sysfs/libsysfs.h" #include "libsysfs/dlist.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "udevdb.h"
udevsend.c +1 -0
@@ -36,6 +36,7 @@#include <linux/stddef.h> #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udevd.h" #include "logging.h"
Quoted 9 lines · Kay Sievers
Here we replace the various
fgets()with ammap()call for the config file reading, due to the reported performance problems with klibc.Thanks to Patrick's testing, it makes a very small, close to nothing speed gain for libc users, but a 6 times speed increase for klibc users with a 1000 line config file.
I've created a udev_lib.[hc] for this and also moved all the generic stuff from
udev.hin there and uninlined the functions.
Very nice. I also fixed udevtest so that it will build properly with this change. Applied.
thanks,
greg k-h
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id70&alloc_id638&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel