This started to look like a 32/64 problem and I think it is. If you
trace the cmpswap, at some point we see 100000000 as a value, just
like somebody added 1 to ffffffff, and it went to, not 0, as expected,
but a bigger value.

See this code:

long
syssemacquire(uint32 *arg)
{
        int block;
        long *addr;
        Segment *s;

        addr = uvalidaddr(arg[0], sizeof(long), 1);
        evenaddr(arg[0]);
        block = arg[1];

        if((s = seg(up, arg[0], 0)) == nil)
                error(Ebadarg);
        if(*addr < 0)
                error(Ebadarg);
        return semacquire(s, addr, block);
}

And note how the u32int is actually converted to a pointer to a long,
which is 64 bits. I put a panic in there on sizeof(*addr) !=
sizeof(*arg) and bang! away we go.

So it's a 32/64 bit cleanliness problem. And it's not just for go,
it's for everything.

This is a huge problem as pentium is little-endian and you're going to
end up trashing data. Bad.

I will try to put a fix in now. We just need to be a little cleaner
about realizing that the syscall interface is always 32 bits, even
when 9vx is built as 64 bits. This is pretty much the TOS thing all
over again.

ron

Reply via email to