On Wed, Jul 24, 2024, at 13:54, Pierre Joye wrote:
> Hi Rob,
>
>
> On Wed, Jul 24, 2024 at 3:17 PM Rob Landers <rob@bottled.codes> wrote:
> >
> > Hello internals,
> >
> > Last night I went down a rabbit hole with Frankenphp: https://github.com/dunglas/frankenphp/pull/933
> >
> > It isn't 100% clear to me what values `ts_resource(id)` holds and if it needs to be freed/allocated per request or per thread. The performance impact is huge to reallocate on every request (mostly due to the global mutex during allocation). Is anyone familiar with this and could help reviewing the changes there?
>
> I suppose you already looked, but if not, maybe it gives you some direction(s).
>
> The key part is kind of documented here:
>
> https://github.com/php/php-src/blob/8e93eb2e79cea5fcca6769b46a429de042660da9/TSRM/TSRM.c#L417
>
> tsrm knows nothing about requests but only threads.Its jobs are about
> threads data.
>
> A good start (surely already looked) are apache and litespeed (or
> embed) for php8, however besides the API names change, the behavior or
> goals of each ts_ or tsrm_ functions remain the same as what we had
> with 5.x. One with a very similar modus operandi than Franken was
> ISAPI for IIS. Mind the names changes, dapt to php8's new names (and
> some behaviors) but the basics and core flows have been kept.
>
> If you know (~) how many threads franken is going to need, tsrm allows
> you to preallocate the rsc slots using tsrm_startup_ex. It uses
> tsrm_startup, a more powerful version, which lets franken define how
> many rsc per thread will be preallocated. I suppose that could help a
> bit performance wise:
>
> https://github.com/php/php-src/blob/8e93eb2e79cea5fcca6769b46a429de042660da9/main/main.c#L2716C13-L2716C25
>
> As per the last question, about when to free them:
> tsrm_shutdown (franken shutdown) will free all rsc
>
> When a thread is detached (franken kills it for example),
> ts_free_thread needs to be called to kill its rsc. They will be freed
> anyway too but good to be clean.
>
> The tsrm resource management will also automatically purge orphan rsrc
> (f.e. when a thread dies unexpectedly and ts_free_thread could not be
> called).
>
> Long story short, the TSRM API is very flexible, how and when you
> alloc/free rsrc is basically up to you. It is possible to keep some
> around in the root thread (and be used in other threads, given the
> root thread id is known (can be 0 or else depending how franken
> managed them.
>
> I hope it helps and did not say too many outdated/wrong explanations :).
>
> Btw, Welting rewrote that part with Dmitry back then to fix long
> standing issues (and drop TSRM_LS/DC/CC uses), not sure if he is still
> around but he may help.
>
> Best,
> --
> Pierre
>
> @pierrejoye | http://www.libgd.org
>
Hey Pierre,
Thank you! This helps tremendously.
> A good start (surely already looked) are apache and litespeed (or
> embed) for php8, however besides the API names change, the behavior or
> goals of each ts_ or tsrm_ functions remain the same as what we had
> with 5.x. One with a very similar modus operandi than Franken was
> ISAPI for IIS. Mind the names changes, dapt to php8's new names (and
> some behaviors) but the basics and core flows have been kept.
I looked at litespeed but not apache, so I will look to that as well.
> If you know (~) how many threads franken is going to need, tsrm allows
> you to preallocate the rsc slots using tsrm_startup_ex. It uses
> tsrm_startup, a more powerful version, which lets franken define how
> many rsc per thread will be preallocated. I suppose that could help a
> bit performance wise:
The number of threads are static (at least for now), so we should def do this.
> Long story short, the TSRM API is very flexible, how and when you
> alloc/free rsrc is basically up to you. It is possible to keep some
> around in the root thread (and be used in other threads, given the
> root thread id is known (can be 0 or else depending how franken
> managed them.
Ah, so this is where I was getting confused. It's unclear what the "id" is and what it is used for. For example, I see the engine has a couple of ids (compiler/execution) but I'm unclear what the sapi should be doing with them. Should these "ids" be different per thread, or is it just an arbitrary key?
— Rob