Hey Lang,
I can’t remember anymore but I think I haven’t tried with -femulated-tls.
I also forwarded the question to the Cling people because I think they got it running – but also haven’t heard back from there. I decided against emulated-tls and tried resolving the Windows symbols myself by adding another IR file to it which was compiled as the following:
extern “C”
{
void Sleep(unsigned long dwMilliseconds);
static constexpr int EpochStart = std::numeric_limits::min();
unsigned int _tls_index = 0;
int _Init_global_epoch = EpochStart;
int _Init_thread_epoch = EpochStart;
void _Init_thread_header(volatile int* ptss)
{
while(true)
{
/* Try to acquire the first initialization lock */
int oldTss = _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptss), -1, 0);
if(oldTss == -1)
{
/* Busy, wait for the other thread to do the initialization */
Sleep(0);
continue;
}
/* Either we acquired the lock and the caller will do the initializaion
or the initialization is complete and the caller will skip it */
break;
}
}
void _Init_thread_footer(int *ptss)
{
ptss = _InterlockedIncrement(reinterpret_cast<long>(&_Init_global_epoch));
}
void _Init_thread_abort(volatile int* ptss)
{
/* Abort the initialization */
_InterlockedAnd(reinterpret_cast<volatile long*>(ptss), 0);
}
}
This was good enough for me until I hear a better way to do this – cause I got a feel that this is not really working? However my static variables were only initialized once no matter how many threads I threw at.
I haven’t mentioned that solution yet cause I’m not much confident about it’s reliability. Maybe I should show this to the cling people too…
Kind greetings
Björn