Date: Thu, 18 Oct 2001 03:51:56 +0400 (MSD) From: "Andrew L. Neporada" <andr@dgap.mipt.ru> To: freebsd-bugs@freebsd.org Cc: freebsd-gnuts-submit@freebsd.org Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB Message-ID: <20011018034848.H24599-100000@nas.dgap.mipt.ru>
next in thread | raw e-mail | index | archive | help
Patch below solves (I hope) this problem. Basic idea of the patch -- to mmap() some moderate amount (8MB) of data rather then entire file (this idea belongs to phk@FreeBSD.org -- see bin/18589). Andrew. P.S. Patch was made against RELENG_4 sources (extern.h v 1.1.1.1.14.1 and regular.c v 1.7.2.2). Unfortunately anoncvs.freebsd.org is down ;-( diff -ruN cmp.orig/extern.h cmp/extern.h --- cmp.orig/extern.h Sun Jul 2 13:28:37 2000 +++ cmp/extern.h Wed Oct 17 06:51:49 2001 @@ -40,9 +40,11 @@ #define DIFF_EXIT 1 #define ERR_EXIT 2 /* error exit code */ -void c_regular __P((int, char *, off_t, off_t, int, char *, off_t, off_t)); -void c_special __P((int, char *, off_t, int, char *, off_t)); -void diffmsg __P((char *, char *, off_t, off_t)); -void eofmsg __P((char *)); +void c_regular __P((int, char *, off_t, off_t, int, char *, off_t, + off_t)); +void c_special __P((int, char *, off_t, int, char *, off_t)); +void diffmsg __P((char *, char *, off_t, off_t)); +void eofmsg __P((char *)); +u_char * remmap __P((u_char *, int, off_t)); extern int lflag, sflag, xflag; diff -ruN cmp.orig/regular.c cmp/regular.c --- cmp.orig/regular.c Sun Jul 2 15:14:42 2000 +++ cmp/regular.c Thu Oct 18 02:48:34 2001 @@ -52,6 +52,7 @@ #include "extern.h" #define ROUNDPAGE(i) ((i) & ~pagemask) +#define MMAP_CHUNK (8*1024*1024) void c_regular(fd1, file1, skip1, len1, fd2, file2, skip2, len2) @@ -59,10 +60,10 @@ char *file1, *file2; off_t skip1, len1, skip2, len2; { - u_char ch, *p1, *p2; + u_char ch, *p1, *p2, *m1, *m2; off_t byte, length, line; int dfound; - off_t pagemask, off1, off2; + off_t pagemask, off1, off2, st1, st2; size_t pagesize; if (skip1 > len1) @@ -81,27 +82,25 @@ off2 = ROUNDPAGE(skip2); length = MIN(len1, len2); - if (length > SIZE_T_MAX) - return (c_special(fd1, file1, skip1, fd2, file2, skip2)); + dfound = 0; + st1 = skip1 - off1; + st2 = skip2 - off2; - if ((p1 = (u_char *)mmap(NULL, (size_t)len1 + skip1 % pagesize, - PROT_READ, MAP_SHARED, fd1, off1)) == (u_char *)MAP_FAILED) - err(ERR_EXIT, "%s", file1); - - madvise(p1, len1 + skip1 % pagesize, MADV_SEQUENTIAL); - if ((p2 = (u_char *)mmap(NULL, (size_t)len2 + skip2 % pagesize, - PROT_READ, MAP_SHARED, fd2, off2)) == (u_char *)MAP_FAILED) - err(ERR_EXIT, "%s", file2); - madvise(p2, len2 + skip2 % pagesize, MADV_SEQUENTIAL); + m1 = remmap(NULL, fd1, off1); + m2 = remmap(NULL, fd2, off2); + if (!m1 || !m2) + c_special(fd1, file1, skip1, fd2, file2, skip2); + /* NOTREACHED */ - dfound = 0; - p1 += skip1 - off1; - p2 += skip2 - off2; - for (byte = line = 1; length--; ++p1, ++p2, ++byte) { + p1 = m1 + st1; + p2 = m2 + st2; + + for (byte = line = 1; length--; ++byte) { if ((ch = *p1) != *p2) { if (xflag) { dfound = 1; - (void)printf("%08qx %02x %02x\n", byte - 1, ch, *p2); + (void)printf("%08qx %02x %02x\n", byte - 1, + ch, *p2); } else if (lflag) { dfound = 1; (void)printf("%6qd %3o %3o\n", byte, ch, *p2); @@ -111,10 +110,41 @@ } if (ch == '\n') ++line; + if (++st1 == MMAP_CHUNK) { + st1 = 0; + off1 += MMAP_CHUNK; + p1 = m1 = remmap(m1, fd1, off1); + } else + ++p1; + if (++st2 == MMAP_CHUNK) { + st2 = 0; + off2 += MMAP_CHUNK; + p2 = m2 = remmap(m2, fd2, off2); + } else + ++p2; + if (!m1 || !m2) + c_special(fd1, file1, skip1, fd2, file2, skip2); + /* NOTREACHED */ } if (len1 != len2) eofmsg (len1 > len2 ? file2 : file1); if (dfound) exit(DIFF_EXIT); +} + +u_char * +remmap(mem, fd, offset) + u_char *mem; + int fd; + off_t offset; +{ + if (mem) + munmap(mem, MMAP_CHUNK); + mem = (u_char *)mmap(NULL, MMAP_CHUNK, PROT_READ, MAP_SHARED, fd, + offset); + if (mem == (u_char *)MAP_FAILED) + return (NULL); + madvise(mem, MMAP_CHUNK, MADV_SEQUENTIAL); + return (mem); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011018034848.H24599-100000>