From: Bruno Haible Date: Sat, 7 Oct 2006 16:52:57 +0000 (+0000) Subject: Make multithread-safe. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1db0b1b1ffcda13179e00b6e926c45c63c5eaaaf;p=thirdparty%2Fgnulib.git Make multithread-safe. --- diff --git a/lib/analyze.c b/lib/analyze.c index 8ed863da41..a7c9ca4c76 100644 --- a/lib/analyze.c +++ b/lib/analyze.c @@ -465,7 +465,6 @@ briefly_report (int changes, struct file_data const filevec[]) int diff_2_files (struct comparison *cmp) { - lin diags; int f; struct change *e, *p; struct change *script; @@ -535,6 +534,10 @@ diff_2_files (struct comparison *cmp) } else { + struct context ctxt; + lin diags; + OFFSET too_expensive; + /* Allocate vectors for the results of comparison: a flag for each line of each file, saying whether that line is an insertion or deletion. @@ -554,31 +557,31 @@ diff_2_files (struct comparison *cmp) /* Now do the main comparison algorithm, considering just the undiscarded lines. */ - xvec = cmp->file[0].undiscarded; - yvec = cmp->file[1].undiscarded; + ctxt.xvec = cmp->file[0].undiscarded; + ctxt.yvec = cmp->file[1].undiscarded; diags = (cmp->file[0].nondiscarded_lines + cmp->file[1].nondiscarded_lines + 3); - fdiag = xmalloc (diags * (2 * sizeof *fdiag)); - bdiag = fdiag + diags; - fdiag += cmp->file[1].nondiscarded_lines + 1; - bdiag += cmp->file[1].nondiscarded_lines + 1; + ctxt.fdiag = xmalloc (diags * (2 * sizeof *fdiag)); + ctxt.bdiag = fdiag + diags; + ctxt.fdiag += cmp->file[1].nondiscarded_lines + 1; + ctxt.bdiag += cmp->file[1].nondiscarded_lines + 1; - heuristic = speed_large_files; + ctxt.heuristic = speed_large_files; /* Set TOO_EXPENSIVE to be approximate square root of input size, bounded below by 256. */ too_expensive = 1; for (; diags != 0; diags >>= 2) too_expensive <<= 1; - too_expensive = MAX (256, too_expensive); + ctxt.too_expensive = MAX (256, too_expensive); files[0] = cmp->file[0]; files[1] = cmp->file[1]; compareseq (0, cmp->file[0].nondiscarded_lines, - 0, cmp->file[1].nondiscarded_lines, minimal); + 0, cmp->file[1].nondiscarded_lines, minimal, &ctxt); - free (fdiag - (cmp->file[1].nondiscarded_lines + 1)); + free (ctxt.fdiag - (cmp->file[1].nondiscarded_lines + 1)); /* Modify the results slightly to make them prettier in cases where that can validly be done. */ diff --git a/lib/diffseq.h b/lib/diffseq.h index 1c5a5c280e..cc00068660 100644 --- a/lib/diffseq.h +++ b/lib/diffseq.h @@ -52,33 +52,38 @@ #define OFFSET_MAX \ ((((OFFSET)1 << (sizeof (OFFSET_MAX) * CHAR_BIT - 2)) - 1) * 2 + 1) -/* Vectors being compared. */ -static const ELEMENT *xvec, *yvec; - -/* Vector, indexed by diagonal, containing 1 + the X coordinate of the point - furthest along the given diagonal in the forward search of the edit - matrix. */ -static OFFSET *fdiag; - -/* Vector, indexed by diagonal, containing the X coordinate of the point - furthest along the given diagonal in the backward search of the edit - matrix. */ -static OFFSET *bdiag; - -#ifdef USE_HEURISTIC -/* This corresponds to the diff -H flag. With this heuristic, for - vectors with a constant small density of changes, the algorithm is - linear in the vectors size. This is unlikely in typical uses of - fstrcmp, and so is usually compiled out. Besides, there is no - interface to set it true. */ -int heuristic; -#endif - -/* Edit scripts longer than this are too expensive to compute. */ -static OFFSET too_expensive; - -/* Snakes bigger than this are considered `big'. */ -#define SNAKE_LIMIT 20 +/* + * Context of comparison operation. + */ +struct context +{ + /* Vectors being compared. */ + const ELEMENT *xvec; + const ELEMENT *yvec; + + /* Vector, indexed by diagonal, containing 1 + the X coordinate of the point + furthest along the given diagonal in the forward search of the edit + matrix. */ + OFFSET *fdiag; + + /* Vector, indexed by diagonal, containing the X coordinate of the point + furthest along the given diagonal in the backward search of the edit + matrix. */ + OFFSET *bdiag; + + #ifdef USE_HEURISTIC + /* This corresponds to the diff -H flag. With this heuristic, for + vectors with a constant small density of changes, the algorithm is + linear in the vectors size. */ + int heuristic; + #endif + + /* Edit scripts longer than this are too expensive to compute. */ + OFFSET too_expensive; + + /* Snakes bigger than this are considered `big'. */ + #define SNAKE_LIMIT 20 +}; struct partition { @@ -119,12 +124,12 @@ struct partition static void diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, - struct partition *part) + struct partition *part, struct context *ctxt) { - OFFSET *const fd = fdiag; /* Give the compiler a chance. */ - OFFSET *const bd = bdiag; /* Additional help for the compiler. */ - const ELEMENT *const xv = xvec; /* Still more help for the compiler. */ - const ELEMENT *const yv = yvec; /* And more and more . . . */ + OFFSET *const fd = ctxt->fdiag; /* Give the compiler a chance. */ + OFFSET *const bd = ctxt->bdiag; /* Additional help for the compiler. */ + const ELEMENT *const xv = ctxt->xvec; /* Still more help for the compiler. */ + const ELEMENT *const yv = ctxt->yvec; /* And more and more . . . */ const OFFSET dmin = xoff - ylim; /* Minimum valid diagonal. */ const OFFSET dmax = xlim - yoff; /* Maximum valid diagonal. */ const OFFSET fmid = xoff - yoff; /* Center diagonal of top-down search. */ @@ -227,7 +232,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, With this heuristic, for vectors with a constant small density of changes, the algorithm is linear in the vector size. */ - if (c > 200 && big_snake && heuristic) + if (c > 200 && big_snake && ctxt->heuristic) { OFFSET best = 0; @@ -304,7 +309,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, /* Heuristic: if we've gone well beyond the call of duty, give up and report halfway between our best results so far. */ - if (c >= too_expensive) + if (c >= ctxt->too_expensive) { OFFSET fxybest; OFFSET bxybest; @@ -376,10 +381,11 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, expensive it is. */ static void -compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal) +compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, + bool find_minimal, struct context *ctxt) { - const ELEMENT *xv = xvec; /* Help the compiler. */ - const ELEMENT *yv = yvec; + const ELEMENT *xv = ctxt->xvec; /* Help the compiler. */ + const ELEMENT *yv = ctxt->yvec; /* Slide down the bottom initial diagonal. */ while (xoff < xlim && yoff < ylim && xv[xoff] == yv[yoff]) @@ -406,11 +412,11 @@ compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minima struct partition part IF_LINT (= {0}); /* Find a point of correspondence in the middle of the vectors. */ - diag (xoff, xlim, yoff, ylim, find_minimal, &part); + diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt); /* Use the partitions to split this problem into subproblems. */ - compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal); - compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal); + compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt); + compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt); } }