1. atomocity depends on the cpu and compiler.
x86 guarentees that even byte accesses are atomic (but not long longs, as these are emulated on 32bit chips like x86).
other cpus have only word (ie: 32bit) accesses, and need to use reads to avoid changing parts of the data.
atomic operations are available on most cpus (either full bus locks on x86, or write-if-still-equal on arm).
compilers can steamroller over everything by rearranging everything. Calling a opaque libc/system function like a mutex lock should ensure no memory accesses get rearranged over the call.
you can also declare types as volatile if you're doing some lockless unatomic syncs - just make SURE that your data type is a machine word, and that you're not running on some really cheap multi-processor system that has no cache coherency. or in other words, don't depend on volatile for anything whatsoever at the hardware level.
2.
https://gcc.gnu.org/onlinedocs/gcc-4.1. ... ltins.htmlfor microsoft compilers, you need to depend upon the windows API instead - InterlockedAdd for instance. naturally, this sucks in portable code (but then so does using gcc-specifics)
C11 has threads.h and stdatomic.h but it'll be a long time before those will actually be usable... msvc users are still stuck with C89...
3. Yup, you'll need to abstract that with two sets of functions. See 5.
note that in windows, a 'mutex' is an inter-process thing. you'll likely want to use 'critical sections', which is what windows calls intra-process mutexes.
4. Yup, good luck with that when it comes to pretty much every single windows function potentially calling SendMessage. If you use mutexes inside your window handler, you are pretty much screwed.
5. FTE has had thread helpers for ages now, but didn't really do too much with them.
It now uses them for directsound mixing (yay, lower mixahead with rtlights), independant player physics (because hitting exactly 77fps with rtlights is hard), map relighting (who needs rtlights anyway), and of course a couple of worker threads to load textures (there are a LOT of textures when your rtlights use specular+bumps+luma+etc etc...) and stuff with.
The worker thread stuff allows me to queue work on a specific thread (either the main thread or the worker thread) and post things from one side to the other. The worker does its thing and posts the 'finished' product back to the main thread which then links it in accordingly (uploading it to gl in the case of textures). because they don't touch each other's stuff, there's no sync conditions between threads (although if your main thread expects a result too soon, you can still have race conditions, but you can test for these by bogging down the worker with some Sleep calls).
you can get away with the worker using cvar values, but don't use cvar strings as the pointer can become invalid at inopertune times.
Stuff with no return value like Con_Printf can include a little bit of code to check if its the main thread, and if not, post and return.
You'll need to very carefully read through the functions your thread calls to make sure its all thread safe, you WILL get hard-to-track bizzare errors if you fail to be truely thorough.
but yeah, the easy way to do it is to post function+data pointers and wait for a response (while not waiting, of course).
cunning use of 'condition variables' can allow your worker to wake up once something is posted to it, without any busy waits.
I guess in windows you could just use PostMessage and have your worker just block in a GetMessage message loop, and then post the result back to the main window (and use SendMessage when you want to sync). But yeah, windows-specific solutions suck.
.