-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Fix MSVC build of threading code #13970
Conversation
Ah, yeah, with mingw we get
so
It's not possible to export a thread-local variable from a dll: https://sourceforge.net/p/mingw-w64/mailman/message/31777672/ So the approach for dealing with |
What does mingw support for exporting TLS? |
|
Curious. I think that means that if we want TLS support everywhere, we would need to simulate it. That could be annoying, but it might give better efficiency than we have now, and avoid the need to use a modified version of llvm... |
What do you mean by better efficiency? I think gcc support a emulate tls mode (not sure which ABI) that is much less efficient than the native TLS on windows. |
I should say I was using unpatched LLVM 3.7.0 here because I have a copy of that built, I have not tried with the tls branch yet. You have said elsewhere that it does not include a windows implementation of the relevant llvm features though? |
general TLS support is expensive, but I think we could potentially choose to emulate only the parts that can be done efficiently. there are a few other trades that we could potentially do as well. it would still be slower than the current global variable, but I could see it providing some extra flexibility, speed, and/or reliability for certain operations. |
jl_all_task_states = malloc(jl_n_threads * sizeof(jl_thread_task_state_t)); | ||
jl_all_heaps = | ||
#ifdef __cplusplus | ||
// undeclared? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to either go with struct _jl_thread_heap_t
or jl_thread_heap_t
, not half way in-between.
5ca56b6
to
d6dbf88
Compare
@@ -87,7 +92,7 @@ DLLEXPORT void jl_threading_profile(void); | |||
# define JL_ATOMIC_FETCH_AND_ADD(a,b) \ | |||
_InterlockedExchangeAdd((volatile LONG *)&(a), (b)) | |||
# define JL_ATOMIC_COMPARE_AND_SWAP(a,b,c) \ | |||
_InterlockedCompareExchange64(&(a), (c), (b)) | |||
_InterlockedCompareExchange64((volatile LONG64 *)&(a), (c), (b)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would prefer to avoid these casts. can we fix the declarations of a
to not need them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no idea. FETCH_AND_ADD as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like I can get rid of the error and cast here for at least COMPARE_AND_SWAP by changing JL_DEFINE_MUTEX
(and JL_DEFINE_MUTEX_EXT
) to use int64_t volatile m
instead of uint64_t volatile m
. Is that okay on unix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that ends up causing warnings
/src/julia.h:115:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (m ## _mutex == uv_thread_self())
so pick your poison I guess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess i would slightly rather have the cast on the comparison (casting the lhs to a uv_thread_t) rather than the pointer. the failure behavior is a bit more localized in the event the definition changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that doesn't work, uv_thread_t
is a HANDLE
on windows
d:/code/msys64/home/Tony/julia/src/jltypes.c(1910) : error C2446: '==' : no conv
ersion from 'unsigned long' to 'uv_thread_t'
Conversion from integral type to pointer type requires reinterpret_cast,
C-style cast or function-style cast
d:/code/msys64/home/Tony/julia/src/jltypes.c(1910) : error C2040: '==' : 'uv_thr
ead_t' differs in levels of indirection from 'unsigned long'
d6dbf88
to
37a0517
Compare
Use gcc __thread when building with gcc on windows DLLEXPORT JL_THREAD except on MSVC should help with: d:\code\msys64\home\tony\julia\src\julia.h(591) : error C2492: 'jl_pgcstack' : ' thread' data may not have dll interface d:\code\msys64\home\tony\julia\src\julia.h(1485) : error C2492: 'jl_current_task ' : 'thread' data may not have dll interface d:\code\msys64\home\tony\julia\src\julia.h(1486) : error C2492: 'jl_root_task' : 'thread' data may not have dll interface d:\code\msys64\home\tony\julia\src\julia.h(1487) : error C2492: 'jl_exception_in _transit' : 'thread' data may not have dll interface d:\code\msys64\home\tony\julia\src\julia.h(1488) : error C2492: 'jl_task_arg_in_ transit' : 'thread' data may not have dll interface d:/code/msys64/home/Tony/julia/src/jltypes.c(1910) : error C2664: 'LONG64 _Inter lockedCompareExchange64(volatile LONG64 *,LONG64,LONG64)' : cannot convert argum ent 1 from 'volatile uint64_t *' to 'volatile LONG64 *' Types pointed to are unrelated; conversion requires reinterpret_cast, C- style cast or function-style cast d:/code/msys64/home/Tony/julia/src/jltypes.c(1913) : error C2664: 'LONG64 _Inter lockedCompareExchange64(volatile LONG64 *,LONG64,LONG64)' : cannot convert argum ent 1 from 'volatile uint64_t *' to 'volatile LONG64 *' Types pointed to are unrelated; conversion requires reinterpret_cast, C- style cast or function-style cast d:/code/msys64/home/Tony/julia/src/jltypes.c(1993) : error C2664: 'LONG64 _Inter lockedCompareExchange64(volatile LONG64 *,LONG64,LONG64)' : cannot convert argum ent 1 from 'volatile uint64_t *' to 'volatile LONG64 *' Types pointed to are unrelated; conversion requires reinterpret_cast, C- style cast or function-style cast d:/code/msys64/home/Tony/julia/src/jltypes.c(2000) : error C2664: 'LONG64 _Inter lockedCompareExchange64(volatile LONG64 *,LONG64,LONG64)' : cannot convert argum ent 1 from 'volatile uint64_t *' to 'volatile LONG64 *' Types pointed to are unrelated; conversion requires reinterpret_cast, C- style cast or function-style cast
to move casts from JL_ATOMIC_COMPARE_AND_SWAP to JL_LOCK/JL_UNLOCK
these don't seem to be needed
0a6663c
to
46b8bf9
Compare
This is mostly made redundant by #14083. Will move the remaining bit over there once I get a chance to build it on msvc. |
Not sure if this code actually works on Windows (LLVM 3.7.0 crashes at the start of bootstrap with a
Relocation type not implemented yet! UNREACHABLE executed at /home/Tony/julia/deps/srccache/llvm-3.7.0/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp:230!
), but at least we can check whether it builds. Some of the!defined(_OS_WINDOWS_)
in here should maybe actually be!defined(_COMPILER_MICROSOFT_)
, but we can sort that out when newer LLVM and the threading code are closer to being enabled by default.