On 2019-05-03, Eric V. Smith wrote:
I'm just saying that if passing around a parameter is the solution to not using global state or TLS, then having a parameter-less accessor function to that state doesn't solve the problem: you're still using global state or TLS.
Thanks for the clarity. So the options seem to be:
A) don't support multiple interpreters per process
B) use TLS or some similar mechanism
C) explicitly pass a context pointer to every single CPython API
It's likely we all agree that A is not what we want. We are already trying to support multiple interpreters, even though the current implementation has a number of issues. I guess we could decide "forget it" and rip that all out. Eric Snow would be sad. ;-P
Regarding B vs C, is the only reason to prefer C due to performance? If so, I think it is not worth the pain of it. Based on my small amount of knowledge, TLS can be really cheap. I found this article that has some benchmarks:
https://david-grs.github.io/tls_performance_overhead_cost_linux/
Again, TLS is a platform specific mechanism so maybe it is worse on Windows, for example. However, it seems to me that there should be some way to do it with relatively small overhead.
Passing context everywhere doesn't come for free either. You are probably using up another register (or pushing something on the stack, depending on the ABI). If you don't need the context often and you don't switch threads often, option B is likely faster.
That's assuming that we can make the plaform optimized TLS work for how CPython uses PyThreadState. In currrent CPython, we don't use it and instead to atomic writes to memory. E.g. _PyThreadState_Swap().