Hi internals,
There is an issue with max_execution_time on MacOS, probably only
MacOS 14 on Apple Silicon, that causes timeouts to fire too early [1].
max_execution_time is implemented with setitimer(ITIMER_PROF) on this
platform, and the SIGPROF
signal is delivered too early for some
reason. Switching to ITIMER_REAL appears to fix the issue, and Manuel
Kress opened a PR [3].
Are there objections against switching to ITIMER_REAL on MacOS (Apple
Silicon only) in all currently supported PHP versions? (next 8.2.x,
8.3.x, 8.x)
Apart from fixing the issue, this would introduce the following minor
breaking changes:
- max_execution_time on MacOS would be based on wall-clock time rather
than CPU time, so the time spent in I/O,sleep()
, and syscalls in
general would count towards the max_execution_time - The
SIGALRM
signal would be used instead of theSIGPROF
signal
(usingSIGALRM
conflicts withpcntl_alarm()
, butSIGPROF
conflicts
with profilers). As noted by Dmitry, it also conflicts withsleep()
on
some platforms, however this should be safe on MacOS.
Currently max_execution_time is based on wall-clock time on ZTS and
Windows, and CPU time otherwise. On Linux and FreeBSD, wall-clock time
can also be used when building with
--enable-zend-max-execution-timers. Máté proposed to add a wall-clock
based timeout in the past [2] but the discussion has stalled. Any
thoughts about eventually switching other platforms to wall-clock
timeouts in the next 8.x ?
TL;DR:
- Any objection about using wall-clock max_execution_time and
SIGALRM
on MacOS Apple Silicon in all supported versions? - Thoughts about using wall-clock timeouts on all platforms in the next 8.x ?
[1] https://github.com/php/php-src/issues/12814
[2] https://github.com/php/php-src/pull/6504
[3] https://github.com/php/php-src/pull/13567
Best Regards,
Arnaud
Hi internals,
There is an issue with max_execution_time on MacOS, probably only
MacOS 14 on Apple Silicon, that causes timeouts to fire too early [1].
max_execution_time is implemented with setitimer(ITIMER_PROF) on this
platform, and theSIGPROF
signal is delivered too early for some
reason. Switching to ITIMER_REAL appears to fix the issue, and Manuel
Kress opened a PR [3].Are there objections against switching to ITIMER_REAL on MacOS (Apple
Silicon only) in all currently supported PHP versions? (next 8.2.x,
8.3.x, 8.x)Apart from fixing the issue, this would introduce the following minor
breaking changes:
- max_execution_time on MacOS would be based on wall-clock time rather
than CPU time, so the time spent in I/O,sleep()
, and syscalls in
general would count towards the max_execution_time- The
SIGALRM
signal would be used instead of theSIGPROF
signal
(usingSIGALRM
conflicts withpcntl_alarm()
, butSIGPROF
conflicts
with profilers). As noted by Dmitry, it also conflicts withsleep()
on
some platforms, however this should be safe on MacOS.Currently max_execution_time is based on wall-clock time on ZTS and
Windows, and CPU time otherwise. On Linux and FreeBSD, wall-clock time
can also be used when building with
--enable-zend-max-execution-timers. Máté proposed to add a wall-clock
based timeout in the past [2] but the discussion has stalled. Any
thoughts about eventually switching other platforms to wall-clock
timeouts in the next 8.x ?TL;DR:
- Any objection about using wall-clock max_execution_time and
SIGALRM
on MacOS Apple Silicon in all supported versions?- Thoughts about using wall-clock timeouts on all platforms in the next 8.x ?
[1] https://github.com/php/php-src/issues/12814
[2] https://github.com/php/php-src/pull/6504
[3] https://github.com/php/php-src/pull/13567Best Regards,
Arnaud
This sounds like a bug with Mac vs. a PHP issue. That being said, the
biggest issue between changing these clocks is that ITIMER_PROF is
(practically, but not explicitly) monotonic. ITIMER_REAL can go
backwards (NTP clock adjustments) which might have interesting
side-effects if the clock is adjusted.
The problem might actually be using ITIMER_PROF, which "Measures CPU
time used by the process, including both user space and kernel space"
and usage of sockets/threads might give an "accelerated" value while
maybe ITIMER_VIRTUAL is the one we should be using since it "Measures
CPU time used by the process (user space)" which won't count kernel
timings.
Robert Landers
Software Engineer
Utrecht NL
Hi Robert,
This sounds like a bug with Mac vs. a PHP issue.
This is what I believe as well. FWIW I was able to reproduce the issue
outside of PHP [2]. I've reported the bug to Apple, but I don't expect
it to be fixed quickly, if at all.
That being said, the
biggest issue between changing these clocks is that ITIMER_PROF is
(practically, but not explicitly) monotonic. ITIMER_REAL can go
backwards (NTP clock adjustments) which might have interesting
side-effects if the clock is adjusted.
Good point. Do you have references about ITIMER_REAL using a
non-monotonic clock, besides the lack of specification regarding the
clock? Based on experiments and the code [1], I think that ITIMER_REAL
uses a monotonic clock on MacOS. It's not ideal to rely on that, and
we should use a better specified timer mechanism if we eventually
switch to wall-clock time on all platforms, but it seems reasonable as
a workaround for the ITIMER_PROF bug on MacOS/Apple Silicon.
The problem might actually be using ITIMER_PROF, which "Measures CPU
time used by the process, including both user space and kernel space"
and usage of sockets/threads might give an "accelerated" value while
maybe ITIMER_VIRTUAL is the one we should be using since it "Measures
CPU time used by the process (user space)" which won't count kernel
timings.
Unfortunately ITIMER_VIRTUAL is not really useful as a
max_execution_time implementation as it will basically never fire in a
syscall-heavy workload. E.g. after replacing ITIMER_PROF by
ITIMER_VIRTUAL in [2], the program runs for well over the specified
time before receiving a signal, despite consuming a considerable
amount of resources.
[1] https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_time.c#L432
[2] https://gist.github.com/arnaud-lb/012195a2fe4d3a2c1bff530a73ae6b11
Best Regards,
Arnaud
Hi Robert,
This sounds like a bug with Mac vs. a PHP issue.
This is what I believe as well. FWIW I was able to reproduce the issue
outside of PHP [2]. I've reported the bug to Apple, but I don't expect
it to be fixed quickly, if at all.That being said, the
biggest issue between changing these clocks is that ITIMER_PROF is
(practically, but not explicitly) monotonic. ITIMER_REAL can go
backwards (NTP clock adjustments) which might have interesting
side-effects if the clock is adjusted.Good point. Do you have references about ITIMER_REAL using a
non-monotonic clock, besides the lack of specification regarding the
clock? Based on experiments and the code [1], I think that ITIMER_REAL
uses a monotonic clock on MacOS. It's not ideal to rely on that, and
we should use a better specified timer mechanism if we eventually
switch to wall-clock time on all platforms, but it seems reasonable as
a workaround for the ITIMER_PROF bug on MacOS/Apple Silicon.
That was my only concern. That being said, I’m all in favor of wall-clock time, personally. It’s much easier to reason about.
The problem might actually be using ITIMER_PROF, which "Measures CPU
time used by the process, including both user space and kernel space"
and usage of sockets/threads might give an "accelerated" value while
maybe ITIMER_VIRTUAL is the one we should be using since it "Measures
CPU time used by the process (user space)" which won't count kernel
timings.Unfortunately ITIMER_VIRTUAL is not really useful as a
max_execution_time implementation as it will basically never fire in a
syscall-heavy workload. E.g. after replacing ITIMER_PROF by
ITIMER_VIRTUAL in [2], the program runs for well over the specified
time before receiving a signal, despite consuming a considerable
amount of resources.[1] https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_time.c#L432
[2] https://gist.github.com/arnaud-lb/012195a2fe4d3a2c1bff530a73ae6b11Best Regards,
Arnaud
— Rob
Hi
This is what I believe as well. FWIW I was able to reproduce the issue
outside of PHP [2]. I've reported the bug to Apple, but I don't expect
it to be fixed quickly, if at all.
Is the bug report public / can you provide a link to it?
Best regards
Tim Düsterhus
Hi Tim,
The report submitted to Apple via Feedback Assistant is not public,
but here is a mirror:
https://openradar.appspot.com/radar?id=5583058442911744
Best regards,
Arnaud
Hi
This is what I believe as well. FWIW I was able to reproduce the issue
outside of PHP [2]. I've reported the bug to Apple, but I don't expect
it to be fixed quickly, if at all.Is the bug report public / can you provide a link to it?
Best regards
Tim Düsterhus
Hi internals,
There is an issue with max_execution_time on MacOS, probably only
MacOS 14 on Apple Silicon, that causes timeouts to fire too early [1].
max_execution_time is implemented with setitimer(ITIMER_PROF) on this
platform, and theSIGPROF
signal is delivered too early for some
reason. Switching to ITIMER_REAL appears to fix the issue, and Manuel
Kress opened a PR [3].Are there objections against switching to ITIMER_REAL on MacOS (Apple
Silicon only) in all currently supported PHP versions? (next 8.2.x,
8.3.x, 8.x)Apart from fixing the issue, this would introduce the following minor
breaking changes:
- max_execution_time on MacOS would be based on wall-clock time rather
than CPU time, so the time spent in I/O,sleep()
, and syscalls in
general would count towards the max_execution_time- The
SIGALRM
signal would be used instead of theSIGPROF
signal
(usingSIGALRM
conflicts withpcntl_alarm()
, butSIGPROF
conflicts
with profilers). As noted by Dmitry, it also conflicts withsleep()
on
some platforms, however this should be safe on MacOS.Currently max_execution_time is based on wall-clock time on ZTS and
Windows, and CPU time otherwise. On Linux and FreeBSD, wall-clock time
can also be used when building with
--enable-zend-max-execution-timers. Máté proposed to add a wall-clock
based timeout in the past [2] but the discussion has stalled. Any
thoughts about eventually switching other platforms to wall-clock
timeouts in the next 8.x ?TL;DR:
- Any objection about using wall-clock max_execution_time and
SIGALRM
on MacOS Apple Silicon in all supported versions?- Thoughts about using wall-clock timeouts on all platforms in the next 8.x ?
[1] https://github.com/php/php-src/issues/12814
[2] https://github.com/php/php-src/pull/6504
[3] https://github.com/php/php-src/pull/13567Best Regards,
Arnaud
FWIW, Cygwin and IBM i are also using wall time, because these platforms
don't do execution time. IIRC, the difference between platforms with how
max_execution_time is counted doesn't seem to be documented last I checked.
Hi Calvin,
FWIW, Cygwin and IBM i are also using wall time, because these platforms
don't do execution time.
Thank you for the additional info.
IIRC, the difference between platforms with how
max_execution_time is counted doesn't seem to be documented last I checked.
Currently the max_execution_time documentation has a note about that,
but it only mentions Windows:
https://www.php.net/manual/en/info.configuration.php#ini.max-execution-time
On non Windows systems, the maximum execution time is not affected by system calls, stream operations etc. Please see theset_time_limit()
function for more details.
Best Regards,
Arnaud
Hello,
I'm in favor of merging Arnaud's patch for macOS while waiting for a better
solution like relying on Grand Central Dispatch or another non-signal-based
solution (https://github.com/php/php-src/pull/13468), which would allow
max_execution_time to work with ZTS builds on mac as well.
I'm also in favor of using wall-clock time wherever possible (disclaimer:
I'm the original author of this feature for Linux and FreeBSD).
Best,
Hi internals,
There is an issue with max_execution_time on MacOS, probably only
MacOS 14 on Apple Silicon, that causes timeouts to fire too early [1].
max_execution_time is implemented with setitimer(ITIMER_PROF) on this
platform, and theSIGPROF
signal is delivered too early for some
reason. Switching to ITIMER_REAL appears to fix the issue, and Manuel
Kress opened a PR [3].Are there objections against switching to ITIMER_REAL on MacOS (Apple
Silicon only) in all currently supported PHP versions? (next 8.2.x,
8.3.x, 8.x)Apart from fixing the issue, this would introduce the following minor
breaking changes:
- max_execution_time on MacOS would be based on wall-clock time rather
than CPU time, so the time spent in I/O,sleep()
, and syscalls in
general would count towards the max_execution_time- The
SIGALRM
signal would be used instead of theSIGPROF
signal
(usingSIGALRM
conflicts withpcntl_alarm()
, butSIGPROF
conflicts
with profilers). As noted by Dmitry, it also conflicts withsleep()
on
some platforms, however this should be safe on MacOS.Currently max_execution_time is based on wall-clock time on ZTS and
Windows, and CPU time otherwise. On Linux and FreeBSD, wall-clock time
can also be used when building with
--enable-zend-max-execution-timers. Máté proposed to add a wall-clock
based timeout in the past [2] but the discussion has stalled. Any
thoughts about eventually switching other platforms to wall-clock
timeouts in the next 8.x ?TL;DR:
- Any objection about using wall-clock max_execution_time and
SIGALRM
on MacOS Apple Silicon in all supported versions?- Thoughts about using wall-clock timeouts on all platforms in the next
8.x ?[1] https://github.com/php/php-src/issues/12814
[2] https://github.com/php/php-src/pull/6504
[3] https://github.com/php/php-src/pull/13567Best Regards,
Arnaud
For reference: There is also this RFC for max_execution_wall_time that was
discussed four years ago. https://externals.io/message/112492#112492