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.

Reply via email to