How to use C-land variable from Cmm-land?
Yuras Shumovich
shumovichy at gmail.com
Mon Dec 10 13:46:18 CET 2012
On Mon, 2012-12-10 at 10:58 +0000, Simon Marlow wrote:
> On 08/12/12 23:12, Yuras Shumovich wrote:
> > I tried to hack stg_putMVarzh directly:
> >
> > if (enabled_capabilities == 1) {
> > info = GET_INFO(mvar);
> > } else {
> > ("ptr" info) = ccall lockClosure(mvar "ptr");
> > }
>
> You should use n_capabilities, not enabled_capabilities. The latter
> might be 1, even when there are multiple capabilities actually in use,
> while the RTS is in the process of migrating threads.
Could you please elaborate? setNumCapabilities is guarded with
asquireAllCapabilities, so all threads are in scheduler. And threads
will be migrated from disabled capabilities before they get a chance to
put/take mvar.
I changed my mind re enabled_capabilities/n_capabilities a number of
times during the weekend. Most likely you are right, and I should use
n_capabilities. But I'll appreciate if you find time to explain it for
me.
>
> > But got no speedup at all.
> > The generated asm (amd64):
> >
> > movl $enabled_capabilities,%eax
> > cmpq $1,%rax
> > je .Lcgq
> > .Lcgp:
> > movq %rbx,%rdi
> > subq $8,%rsp
> > movl $0,%eax
> > call lockClosure
> > addq $8,%rsp
> > .Lcgr:
> > cmpq $stg_MVAR_CLEAN_info,%rax
> > jne .Lcgu
> > {...}
> > .Lcgq:
> > movq (%rbx),%rax
> > jmp .Lcgr
> >
> >
> > It moves enabled_capabilities into %eax and then compares 1 with %rax.
> > It looks wrong for me: the highest part of %rax remains uninitialized.
>
> As Axel noted, this is correct.
The problem was that "movl $enabled_capabilities,%eax" loaded the
address of enabled_capabilities, not a value. (Again, why does it use
32bit register? The value is 32bit on linux, but the address is 64bit,
isn't it?) So the correct way to use C-land variable is:
if (CInt[enabled_capabilities]) {...}
Not very intuitive, but at least it works.
Thanks,
Yuras
More information about the Glasgow-haskell-users
mailing list