Eliminate all global state
-
- Posts: 10
- Joined: Tue Sep 20, 2016 10:17 pm
Re: Eliminate all global state
But then if you wanted to share the same interpretter across two threads you couldn't. Say if you wanted two interpreters that ran in isolation, then you wanted to take advantage of some of that new threading code in there and have those two threads fire up some threads whose state you wanted to share. Isn't it more flexible to just bite the bullet and pass a context object around?
Re: Eliminate all global state
Sure just have the 2 threads that belong "together" have pointers to the same context data.
As to passing around all of the context data, you'd need to try it and see what type of memory/performance penalty you'd pay.
As to passing around all of the context data, you'd need to try it and see what type of memory/performance penalty you'd pay.
-
- Posts: 10
- Joined: Tue Sep 20, 2016 10:17 pm
Re: RE: Re: Eliminate all global state
Similarly wouldn't there be a performance penalty for using thread local storage? Given that it needs some sort of synchronisation behind the hood?dhylands wrote:Sure just have the 2 threads that belong "together" have pointers to the same context data.
As to passing around all of the context data, you'd need to try it and see what type of memory/performance penalty you'd pay.
Sent from my HUAWEI VNS-L22 using Tapatalk
Re: Eliminate all global state
I think it depends on how the TLS is implemented.
One way is to simply have a global pointer which is "thread context" and the context switcher updates it as it does context switches. The linux kernel uses aligned stacks and then just masks the stack pointer to get the TLS pointer. Neither of those methods requires any synchronization.
One way is to simply have a global pointer which is "thread context" and the context switcher updates it as it does context switches. The linux kernel uses aligned stacks and then just masks the stack pointer to get the TLS pointer. Neither of those methods requires any synchronization.
-
- Posts: 10
- Joined: Tue Sep 20, 2016 10:17 pm
Re: RE: Re: Eliminate all global state
I'm not sure I follow how either of those methods work.dhylands wrote:I think it depends on how the TLS is implemented.
One way is to simply have a global pointer which is "thread context" and the context switcher updates it as it does context switches. The linux kernel uses aligned stacks and then just masks the stack pointer to get the TLS pointer. Neither of those methods requires any synchronization.
For the second suggestion, the Linux kernel idea do you mean you'd keep the TLS in a contiguous block of memory where each TLS block was aligned to avoid false sharing and then to use the thread id to index into that block without having to protect it at all ?
Re: Eliminate all global state
The linux kernel allocates 4K (or 8K) stacks aligned on a 4K (or 8K) boundary.
At one end of the stack (I don't recall which end off the top of my head), the kernel keeps a structure for the thread, which contains information specific to that thread.
You can locate that structure by simply taking the stack pointer and applying a mask.
Under the first method, each thread has its own blob of memory which contains the thread-local data. Let's suppose we have a global called tls which points to the thread-local storage data.
Since the context switcher updates tls to point to the thread-local data, the code can always use tls->data and it will get the data which is specific for that thread. There is no synchronization required because the data is per thread.
https://en.wikipedia.org/wiki/Thread-local_storage
At one end of the stack (I don't recall which end off the top of my head), the kernel keeps a structure for the thread, which contains information specific to that thread.
You can locate that structure by simply taking the stack pointer and applying a mask.
Under the first method, each thread has its own blob of memory which contains the thread-local data. Let's suppose we have a global called tls which points to the thread-local storage data.
Since the context switcher updates tls to point to the thread-local data, the code can always use tls->data and it will get the data which is specific for that thread. There is no synchronization required because the data is per thread.
https://en.wikipedia.org/wiki/Thread-local_storage
-
- Posts: 10
- Joined: Tue Sep 20, 2016 10:17 pm
Re: RE: Re: Eliminate all global state
Ah that makes sense. It's just stored on the stack and a TLS variable will have the same offset on the stack across all threads.dhylands wrote:The linux kernel allocates 4K (or 8K) stacks aligned on a 4K (or 8K) boundary.
At one end of the stack (I don't recall which end off the top of my head), the kernel keeps a structure for the thread, which contains information specific to that thread.
You can locate that structure by simply taking the stack pointer and applying a mask.
Under the first method, each thread has its own blob of memory which contains the thread-local data. Let's suppose we have a global called tls which points to the thread-local storage data.
Since the context switcher updates tls to point to the thread-local data, the code can always use tls->data and it will get the data which is specific for that thread. There is no synchronization required because the data is per thread.
https://en.wikipedia.org/wiki/Thread-local_storage
That boils down to almost the same as having the context in your main function and passing a pointer around, only there's no need to pass it around as we can jump straight to it.