gh-125997: ensure that time.sleep(0) is not delayed on non-Windows platforms#128274
gh-125997: ensure that time.sleep(0) is not delayed on non-Windows platforms#128274picnixz wants to merge 26 commits into
time.sleep(0) is not delayed on non-Windows platforms#128274Conversation
ff959e1 to
80de853
Compare
December 27, 2024 11:05
|
@picnixz Unfortunately, we should seriously review :(. It seems that an assertion failed somewhere. |
Sorry, something went wrong.
|
Ah I think I know what happens. When we raise an OSError from errno we don't clear the errno. So if you chain calls, you need to just ignore them. I'm removing the assertion cc @ZeroIntensity |
Sorry, something went wrong.
Due to how `OSError` are raised from `errno`, we do not clear `errno` afterwards. If we catch `OSError`, then we still have an errno set, and if we call `time.sleep()` just after, we may have `errno != 0` (but we know we handled it so it's fine).
|
If pytime is running on multiple cores, I recommend using raw defined |
Sorry, something went wrong.
|
This wouldn't solve the issue (also because |
Sorry, something went wrong.
|
TIL! Should we assert |
Sorry, something went wrong.
Not sure. It's not really an issue and the function is internal and only for |
Sorry, something went wrong.
|
I think we should. There's no real cost to adding it, and it would be helpful for debugging in the rare case that something goes wrong. |
Sorry, something went wrong.
i have not looked into this too deeply but my understanding is the poll() will also relinquish the CPU since it is a syscall but not necessarily give up the time slice (e.g. if there are no threads with higher priority)
this looks like a good idea, might be the cleanest - just choose TIMER_ABSTIME in the case that the argument to time.sleep() is <=0. as a user, i would just generally expect that sleep() issues a syscall (i.e. relinquish enough control to the kernel and cpython runtime that they can unblock any I/O or other operations that need to be scheduled) but don't really care exactly which one. |
Sorry, something went wrong.
|
I'll commit something tomorrow or the day after using that approach. It would also be nice to avoid the (small) overhead of using |
Sorry, something went wrong.
|
While we're still above the For comparison, the current implementation performances 25x worse: I'll update the comments, docs and tests and push those changes. FTR, the numbers above are in a DEBUG build, but this doesn't change much as on an optimized build, current implementation takes roughly the same amount of time. |
Sorry, something went wrong.
The implementations of `time.sleep(0)` on Windows and POSIX are now handled by the same function. Previously, `time.sleep(0)` on Windows was handled by `pysleep()` while on POSIX platforms, it was handled by `pysleep_zero_posix()`.
|
Ok, so I'm actually back at the starting point. First of all, let's take a step back and understand the issue at hand: Second, I was wrong with Now, let's move back to what template<typename _Rep, typename _Period>
inline void
sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
{
if (__rtime <= __rtime.zero())
return;
...
}So, as we can see, If yes, what about Windows' dedicate Or, if this is really too much of a hassle, we can just... drop that PR (I won't mind) and simply improve the docs saying that |
Sorry, something went wrong.
Using `clock_nanosleep()` would always take more than 50 us.
|
For now, I've decided to revert to the old 3.11 behaviour. If you prefer me to change the docs, I can also do it. I'm leaving for a few days so I won't be able to see the comments. |
Sorry, something went wrong.
|
If I understood correctly the issue, the purpose of this change is to make The problem is that always using |
Sorry, something went wrong.
|
Considering that we would be penalizing FreeBSD (and that using I learned a lot during this but I'm still not comfortable with reverting it back to the previous behaviour. ISTM that the previous behaviour is probably "wrong" (namely, I'm not really sure we should even use |
Sorry, something went wrong.
This is a suggestion for fixing the issue when the timeout is 0. For other timeouts, this does not change the current behaviour (I'm tempted removing the
do-whileloop as we should never have an issue, but I'm not familar with the monotonic C implementation so I left it as is).time.sleep(0)is slower on Python 3.11 than on Python 3.10 #125997