Hi XS people,

This seems the proper venue to share the solution to a bug that has
been bedeviling my CPAN module IPC::MMA on some threaded
systems since its introduction.

The problem affected three array operations that take a Perl list in
their operands: push, unshift, and splice.  The XS interface routines
for all three included code that took the variable pointers from the
Perl stack and put them into a C array:

mm_array_push (array, ...)
    ...
    PREINIT:
        int add_count = items - 1;
        SV *addSVs[add_count];
        int i=0;
    CODE:
        while (i < add_count) addSVs[i++] = ST(i+1);

The C spec is not definitive on when some operations should happen.
The && and || operators are defined to be time-sequential, in that
everything on the left side happens (is evaluated) before anything
on the right side (which doesn't happen if the result of the && or ||
can be determined from the left result).

I thought assignment operators were like that too, in that everything
on the right side should happen before anything on the left side.  But
I found that {addSVs[i]=ST(i+1); i++;} fixed my problems.

So I went on a web search to determine whether the C spec said that
assignment was a time-sequential operator, in which case this would
be a bug in the compiler.  It was a hard search.  Finally I found a
page that settled the issue:
http://www.mail-archive.com/tinycc-de...@nongnu.org/msg02398.html

I was wrong.  The right side can end up using either the original or
incremented value of i.

Why this only showed up on some threaded systems is a puzzler.  In
theory the compiler could generate code in which one thread/core
evaluates the right-side expression while another thread/core computes
the left-side address.  But the overhead of dispatching and converging
two threads would seem greater than just doing the whole statement
in one thread.

Don't know: I've never written a code generator for threads, and my
compiler-writing days are behind me.

Or maybe the correlation with threads was false.  Maybe it was a matter
of different versions of gcc on different systems.  I'll never know but
I'll wonder for quite some time.

Maybe this will help someone someday,
Craig MacKenna

Reply via email to