Thread overview
Thread local variables in betterC
May 09, 2021
Blatnik
May 09, 2021
Blatnik
May 09, 2021
rikki cattermole
May 09, 2021
Blatnik
May 09, 2021
Ali Çehreli
May 09, 2021
Blatnik
May 09, 2021
Imperatorn
May 09, 2021
Blatnik
May 09, 2021

Do thread local variables work in -betterC? Or maybe it's better to ask are they supposed to work in -betterC?

Here's a simple test program:

// test.d
auto a;

extern(C) void main() {
  printf("before... ");
  a = 42;
  printf("after");
}

import core.stdc.stdio;

And here is the output of compiling and running:

$ dmd -betterC test.d; ./test.exe
before... after

$ dmd -betterC -m64 test.d; ./test.exe
before... [program hangs for 3 seconds, and then exits without printing anything else]

So when I compile a 64-bit version, the program just hangs when writing to the thread local variable. But it does work when compiled for 32-bits. So what is the intended outcome here?

May 09, 2021

On Sunday, 9 May 2021 at 18:41:33 UTC, Blatnik wrote:

>

Here's a simple test program:

Whoops, auto a should be int a. Habits :P

May 10, 2021
On 10/05/2021 6:41 AM, Blatnik wrote:
> Do thread local variables work in -betterC? Or maybe it's better to ask are they _supposed_ to work in -betterC?

No.

It is tied to druntime. I.e. on Linux it calls __tls_get_addr to get the address.
May 09, 2021
On Sunday, 9 May 2021 at 18:46:18 UTC, rikki cattermole wrote:
> No.
>
> It is tied to druntime. I.e. on Linux it calls __tls_get_addr to get the address.

Oh. I wish I got a warning about that from the compiler then >.>

Also, why did it work for 32-bits then?
May 09, 2021
On 5/9/21 11:49 AM, Blatnik wrote:

> Also, why did it work for 32-bits then?

This is a long shot, but are you on OSX? I think TLS is handled specially for 32-bit OSX and that may somehow work in this case. (?)

Ali
May 09, 2021
On Sunday, 9 May 2021 at 20:56:01 UTC, Ali Çehreli wrote:
> This is a long shot, but are you on OSX? I think TLS is handled specially for 32-bit OSX and that may somehow work in this case. (?)

Nope, I'm on (64bit) windows.

Another really weird thing is that if I compile this code in VisualD (with the exact same flags, compiler and everything) it runs just fine either as 64-bit or 32-bit..

This really doesn't make any sense at all.

Is there any way at all I can initialize these variables myself without linking with druntime?
May 09, 2021
On Sunday, 9 May 2021 at 21:42:54 UTC, Blatnik wrote:
> On Sunday, 9 May 2021 at 20:56:01 UTC, Ali Çehreli wrote:
>> This is a long shot, but are you on OSX? I think TLS is handled specially for 32-bit OSX and that may somehow work in this case. (?)
>
> Nope, I'm on (64bit) windows.
>
> Another really weird thing is that if I compile this code in VisualD (with the exact same flags, compiler and everything) it runs just fine either as 64-bit or 32-bit..
>
> This really doesn't make any sense at all.
>
> Is there any way at all I can initialize these variables myself without linking with druntime?

Check the assembly
May 09, 2021

On Sunday, 9 May 2021 at 22:55:41 UTC, Imperatorn wrote:

>

Check the assembly

I already did, here's the "wrong" version when I only run $ dmd -betterC -m64 test.d:

Dump of file test.obj

main:
  push        rbp
  mov         rbp,rsp
  mov         rax,qword ptr gs:[58h]

  mov         rcx,qword ptr [rax]
  mov         edx,offset _D4test1ai
  mov         dword ptr [rcx+rdx],42

  xor         eax,eax
  pop         rbp
  ret

And here it is when I run $ dmd -betterC -m64 -c test.d:

Dump of file test.obj

main:
  push        rbp
  mov         rbp,rsp
  push        rbx
  mov         eax,dword ptr [_tls_index] <--------
  mov         rcx,qword ptr gs:[58h]

  mov         rdx,qword ptr [rcx+rax*8]
  mov         ebx,offset _D4test1ai
  mov         dword ptr [rdx+rbx],42

  xor         eax,eax
  pop         rbx
  rbp
  ret

So this just seems like some sort of compiler bug. It doesn't emit the TLS index retrieval unless you compile with -c and link separately.

Also, I've looked into this now, and thread locals should work in -betterC as far as I can tell. There's no mention of them not working on https://dlang.org/spec/betterc.html, and if they really didn't work it would have been mentioned there in bold all caps. It would be pretty important to mention that int a = 0; doesn't work correctly.