On Sat Nov 19 11, Tim Kientzle wrote: > > On Nov 18, 2011, at 12:31 PM, Alexander Best wrote: > > > On Fri Nov 18 11, Tim Kientzle wrote: > >> > >> Take a look at > >> > >> http://libarchive.googlecode.com/svn/trunk/libarchive/archive_read_open_filename.c > >> > >> Especially the comments about detecting "disk-like" devices. > >> I rewrote a bunch of this code to introduce an explicit > >> notion of "strategy" so that we could optimize access > >> to a variety of different devices. > >> > >> This code has a notion of "disk-like" file descriptors and > >> some optimizations for such. There are some comments > >> in there outlining similar optimizations that could be made > >> for "tape-like" or "socket-like" devices. > > > > great you posted that file as reference. i believe most of the stuff done > > there > > should actually be done within lseek(). > > Libarchive runs on a lot of systems other than FreeBSD. > FreeBSD is not the only Unix-like system with this issue, > so that code isn't going to go out of libarchive regardless. > > If you think those same ideas can be used in dd or hd > to speed them up, please send your patches.
i'd like to propose the followup patch for hexdump(1). basically, the logic behind is is this: 1) if the file argument is a fifo, pipe or socket -- goto 4) 2) if the file argument is a tape drive -- goto 4) 3) for all other cases try fseeko(), if that fails -- goto 4) 4) use getchar() you should notice a dramtic increase in speed from something like the following: 'hexdump -s 500m -n32 /dev/random' cheers. alex > > The key point: You cannot unconditionally call lseek() > to skip over data. Instead, treat lseek() as an optimization > that can be used under some circumstances. The > question then becomes one of figuring out when > that optimization can be enabled. > > Tim >
diff --git a/usr.bin/hexdump/display.c b/usr.bin/hexdump/display.c index 991509d..8c8b065 100644 --- a/usr.bin/hexdump/display.c +++ b/usr.bin/hexdump/display.c @@ -35,8 +35,10 @@ static char sccsid[] = "@(#)display.c 8.1 (Berkeley) 6/6/93"; #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/ioctl.h> #include <sys/param.h> #include <sys/stat.h> +#include <sys/conf.h> #include <ctype.h> #include <err.h> @@ -368,7 +370,7 @@ next(char **argv) void doskip(const char *fname, int statok) { - int cnt; + int type; struct stat sb; if (statok) { @@ -380,16 +382,38 @@ doskip(const char *fname, int statok) return; } } - if (S_ISREG(sb.st_mode)) { - if (fseeko(stdin, skip, SEEK_SET)) + if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) { + noseek(); + return; + } + if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { + if (ioctl(fileno(stdin), FIODTYPE, &type)) err(1, "%s", fname); - address += skip; - skip = 0; - } else { - for (cnt = 0; cnt < skip; ++cnt) - if (getchar() == EOF) - break; - address += cnt; - skip -= cnt; + /* + * Most tape drives don't support seeking, + * yet fseeko() would succeed. + */ + if (type & D_TAPE) { + noseek(); + return; + } + } + if (fseeko(stdin, skip, SEEK_SET)) { + noseek(); + return; } + address += skip; + skip = 0; +} + +void +noseek(void) +{ + int count; + + for (count = 0; count < skip; ++count) + if (getchar() == EOF) + break; + address += count; + skip -= count; } diff --git a/usr.bin/hexdump/hexdump.h b/usr.bin/hexdump/hexdump.h index be85bd9..1d4bb85 100644 --- a/usr.bin/hexdump/hexdump.h +++ b/usr.bin/hexdump/hexdump.h @@ -97,6 +97,7 @@ u_char *get(void); void newsyntax(int, char ***); int next(char **); void nomem(void); +void noseek(void); void oldsyntax(int, char ***); size_t peek(u_char *, size_t); void rewrite(FS *);
_______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"