Hi Nikita,

> I think we need to distinguish two cases:
> 
> 1. Globals that are local to a DSO. The majority of globals in extensions is 
> of this
> kind. While it is currently common to declare these globals in an exported
> header, they really shouldn't be. We should move these towards ZEND_TLS
> (__thread). This should be fine on all platforms, including Windows. In 
> unusual
> cases where globals need to be accessed outside the extension,
> getters/setters can be provided (for parts of the structure, or if necessary 
> the
> whole structure).
> 
> Unfortunately some of our code is currently written around the assumption
> that TSRM globals are used, e.g. the STD_INI_ENTRY macros.
> 
This is correct, there is more on that. The current expectation is globals to 
be exported. Take as an example PCRE - while porting to PCRE2, I've used also 
some ZEND_TLS variables, which are still integrated into GINIT. STD_INI_ENTRY 
which has globals as a storage is useful, if one expects the values to be 
changed or read also from somewhere else. In ext/pcre these use cases are 
present - use of real exported globals, use of the local globals, use globals 
to store INI.

Currently, if a module only needs local globals, it'd still declare some 
globals structure to be used with GINIT. Thus, we might need another API like 
GINIT_LOCAL. To use ZEND_TLS, it is actually not necessary to have a structure, 
variables can just be put into a source file. Than GINIT local API wouldn't 
have to pass any globals therefore, what it would need is just to be called 
once per thread, same as the current GINIT does.  

> 
> 2. Globals that are accessed across DSOs. These are the core globals EG, CG,
> BG, etc. On platforms that support it (e.g. Linux) this should use ZEND_TLS as
> well. On platforms that don't, we can use the proposed mechanism. We can
> hardcode the supported globals here, as we don't need to support additional
> extension globals.
> 
> It makes no sense to pay the DSO TLS overhead for the TSRM cache variable,
> and then add the TSRM indirection overhead on top of that, if we can avoid it.
> 
The author of the original RFC Arnauld Le Blanc made some more research 
https://wiki.php.net/rfc/tls. His latest patch was also relying on the offsets, 
but didn't flatten the data structures as Dmitry proposed and it also didn't 
remove the additional TSRMLS_* args as it was done for 7.0 by the other RFC. 
Arnauld's patch did also rely on what we currently call ZEND_TLS in a near 
sense, still having the old structures.

I'd anticipate that we end with two completely different implementations. For 
example, ZEND_TLS is indeed "static __thread", for exporting it would require 
to differentiate extern and static and the visibility. As all the globals are 
currently exported and we don't know how they're used in any external modules, 
there might be BC issues if some are not exported anymore.  Preferably the 
current mechanism were to be improved first, as suggested, then one could think 
about complicating things more ;) There's btw a more detailed doc about TLS in 
ELF bins https://www.akkadia.org/drepper/tls.pdf, we might be not far from that 
if the offset access is implemented. TLS internally is not much different from 
what the implementation in PHP does - there are tables per thread which are 
accessed by some index. Depending on how much improvement would be to see from 
the offset access, it might be acceptable enough instead of having multiple 
implementations and all the maintenance/QA effort.

Regards

Anatol

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to