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