On Apr 30, 2013, at 7:02 PM, Jason Merrill <ja...@redhat.com> wrote: > Releasing the lock is not reliable; if the user interrupts the link with ^C, > the lock will remain. So I adjusted 'make all' to remove the lock early on, > though that only works for the typical case, and users that do something like > 'make cc1plus' could still run into trouble.
I don't like the unreliable nature of the lockā¦ I've been burned so many times over the years from bad locks, I just want to run away screaming, that said. It might be ok to leave it unreliable. > Maybe I should fix Make instead. Well, if you can wait 3 years for a fix. :-) Until then, having something in the gcc build system seems like the right approach. + mem="$(free|sed -n 2p|awk '{print $2}')" 2>/dev/null + if test "$mem" -lt 8000000 2>/dev/null; then + do_link_mutex=yes + else + do_link_mutex=no + fi) when the system doesn't have free, this fails. I think: + mem="$(free|sed -n 2p|awk '{print $2}')" 2>/dev/null + if test "0$mem" -lt 8000000 2>/dev/null; then + do_link_mutex=yes + else + do_link_mutex=no + fi) should fix it. Notice the 0$mem. Also, when there is no free on the system, this fails with the mutex on. I think I might prefer it to fail off, though, not a big issue. if test "0$mem" -lt 8000000 -a "0$mem" -ne 0 2>/dev/null; then I think would flip the default for treeless systems. and last, > cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS) > + $(MAKE) link-mutex > +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \ > - cc1-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS) > + cc1-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS); \ > + $(MAKE) remove-link-mutex > # > # Build hooks: I think this blows error returns from LINKER?! That is deadly. Not cleaning up the lock when the link fails would be down right anti-social, given we already wedge in typical development style builds. The solution is done like this: $ { true && echo remove lock; } || { echo remove lock && false; }; echo $? remove lock 0 $ { false && echo remove lock; } || { echo remove lock && false; }; echo $? remove lock 1 That's old-skool. The new fangled approach, if you can tolerate new tricks would be: $ bash -c "trap 'echo remove lock' 0; true"; echo $? remove lock 0 $ bash -c "trap 'echo remove lock' 0; false"; echo $? remove lock 1 The advantage of this is, even in exceptional cases (but only trivial exceptional cases like ^C), the lock is removed, though, blunting further the fact the lock is poor. I can't help, but wonder, if having a LLINKER like this: LLINKER := 'linkit () { $(MAKE) link-mutex && { { $(LINKER) "$$@" && $(MAKE) remove-link-mutex; } || { $(MAKE) remove-link-mutex && false; } } } && linkit" (pseudo code, one has to ensure quoting and meta characters are right) Then you can use LLINKER or LINKER depending upon if you want to serialize the link. This is then easy to maintain, as there is only one definition of LLINKER. If a mistake was made in the semantic for it, it only would need fixing in the one place, not 8. Ensuring the quoting is right, is the only hard part. If you can tolerate the new school solution, this goes a long way to lessening the impact of the bad lock.