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?
— Rob
Hello internals,
Last night I went down a rabbit hole with Frankenphp:
https://github.com/dunglas/frankenphp/pull/933It 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?— Rob
Interesting results.
Joe Watkins (krakjoe) would be a good person to ask, he's worked on that
and he also did pthreads and parallel. But I'm not sure how active he is
anymore. Gina Banyard (Girgias) or Niels Dossche (nielsdos) will probably
know too.
You can try to ping them in https://chat.stackoverflow.com/rooms/11/php
Thanks,
Peter
Hi Rob,
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:
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
Hi Rob,
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:As per the last question, about when to free them:
tsrm_shutdown (franken shutdown) will free all rscWhen 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
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?
there are two ids you can pass. The rsc ID and the thread ID.
By default the thread ID will be the current thread.
the rsrc is the one you get when creating a new rsc (fetching a non
existent one will create it btw).
I would suggest to read the comments in the implement of ts_resource, lot
of useful information are explained there :)
best,
Pierre
Hi Rob,
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:As per the last question, about when to free them:
tsrm_shutdown (franken shutdown) will free all rscWhen 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.
Sorry, I forgot to copy that link, php5 but core flow is the same:
--
Pierre
@pierrejoye | http://www.libgd.org