for review: bug fix for concurrent writes to `.d' files
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Feb 27 22:32:18 AEDT 1998
Estimated hours taken: 0.75
compiler/modules.m:
Fix a bug with parallel makes where the `.d' files were being
stuffed up because two different invocations of the Mercury
compiler were writing to them at the same time.
The problem occurs because the `.d' file is written out
both when creating the `.c' file and when creating the
`.trans_opt' file, and these steps might happen in parallel.
The fix is to write the dependency file to `<foo>.d.tmp' and
then rename the `.d.tmp' to `.d'. This ensures that the update
to the `.d' file is atomic.
[In theory this is not a 100% portable solution, because
rename() might not be atomic, but in practice it should be
fine, because rename() is atomic on all the platforms of
interest (i.e. all the ones that support parallel GNU make).]
An alternative fix would be to not write out the `.d' files
when creating `.trans_opt' files. This would also be more
efficient. However, the danger is that the `.d' files might
not be updated often enough. I'm not really sure exactly
how often they need to be updated, but the fix using
renaming seems safer.
cvs diff compiler/modules.m
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.56
diff -u -r1.56 modules.m
--- modules.m 1998/02/07 09:55:32 1.56
+++ modules.m 1998/02/27 11:15:15
@@ -509,11 +509,12 @@
MaybeTransOptDeps) -->
globals__io_lookup_bool_option(verbose, Verbose),
{ string__append(ModuleName, ".d", DependencyFileName) },
+ { string__append(ModuleName, ".d.tmp", TmpDependencyFileName) },
maybe_write_string(Verbose, "% Writing auto-dependency file `"),
maybe_write_string(Verbose, DependencyFileName),
maybe_write_string(Verbose, "'..."),
maybe_flush_output(Verbose),
- io__open_output(DependencyFileName, Result),
+ io__open_output(TmpDependencyFileName, Result),
( { Result = ok(DepStream) } ->
{ set__list_to_set(LongDeps0, LongDepsSet0) },
{ set__delete(LongDepsSet0, ModuleName, LongDepsSet) },
@@ -661,10 +662,22 @@
]),
io__close_output(DepStream),
- maybe_write_string(Verbose, " done.\n")
+ io__remove_file(DependencyFileName, _Result2),
+ io__rename_file(TmpDependencyFileName, DependencyFileName,
+ Result3),
+ ( { Result3 = error(Error) } ->
+ { io__error_message(Error, ErrorMsg) },
+ { string__append_list(["can't rename file `",
+ TmpDependencyFileName, "' as `",
+ DependencyFileName, "': ", ErrorMsg],
+ Message) },
+ report_error(Message)
+ ;
+ maybe_write_string(Verbose, " done.\n")
+ )
;
- { string__append_list(["can't open file `", DependencyFileName,
- "' for output."], Message) },
+ { string__append_list(["can't open file `",
+ TmpDependencyFileName, "' for output."], Message) },
report_error(Message)
).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list