-
-
Couldn't load subscription status.
- Fork 33.2k
gh-110693: refactor pending calls and use linked list implementation #125567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,49 +14,38 @@ extern "C" { | |
|
|
||
| typedef int (*_Py_pending_call_func)(void *); | ||
|
|
||
| struct _pending_call { | ||
| typedef struct _pending_call { | ||
| _Py_pending_call_func func; | ||
| void *arg; | ||
| int flags; | ||
| }; | ||
|
|
||
| #define PENDINGCALLSARRAYSIZE 300 | ||
| struct _pending_call *next; | ||
| } _pending_call; | ||
|
|
||
| #define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE | ||
| /* For interpreter-level pending calls, we want to avoid spending too | ||
| much time on pending calls in any one thread, so we apply a limit. */ | ||
| #if MAXPENDINGCALLS > 100 | ||
| # define MAXPENDINGCALLSLOOP 100 | ||
| #else | ||
| # define MAXPENDINGCALLSLOOP MAXPENDINGCALLS | ||
| #endif | ||
| #define MAXPENDINGCALLSLOOP 100 | ||
|
|
||
| /* We keep the number small to preserve as much compatibility | ||
| as possible with earlier versions. */ | ||
| #define MAXPENDINGCALLS_MAIN 32 | ||
| /* For the main thread, we want to make sure all pending calls are | ||
| run at once, for the sake of prompt signal handling. This is | ||
| unlikely to cause any problems since there should be very few | ||
| pending calls for the main thread. */ | ||
| #define MAXPENDINGCALLSLOOP_MAIN 0 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd probably leave this alone, but I'm not opposed to this change. |
||
| #define MAXPENDINGCALLSLOOP_MAIN INT32_MAX | ||
|
|
||
| struct _pending_calls { | ||
| PyThreadState *handling_thread; | ||
| PyMutex mutex; | ||
| /* Request for running pending calls. */ | ||
| /* The number of pending calls. */ | ||
| int32_t npending; | ||
| /* The maximum allowed number of pending calls. | ||
| If the queue fills up to this point then _PyEval_AddPendingCall() | ||
| will return _Py_ADD_PENDING_FULL. */ | ||
| int32_t max; | ||
|
Comment on lines
-48
to
-51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should leave this, for the sake of the "main" pending calls stuff. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would also be worth leaving it for a while, so we can more easily deal with unexpected consequences of switching to an unbounded linked list. |
||
| /* We don't want a flood of pending calls to interrupt any one thread | ||
| for too long, so we keep a limit on the number handled per pass. | ||
| A value of 0 means there is no limit (other than the maximum | ||
| size of the list of pending calls). */ | ||
| int32_t maxloop; | ||
| struct _pending_call calls[PENDINGCALLSARRAYSIZE]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should leave this statically allocated array for the sake of the "main" pending calls. We could go back to the old limit of Of course, we'd still use this for per-interpreter pending calls, since it's already there. |
||
| int first; | ||
| int next; | ||
| _pending_call *head; | ||
|
|
||
| #define _Py_PENDING_CALLS_FREELIST_SIZE 100 | ||
| _pending_call *freelist; | ||
| size_t freelist_num; | ||
| }; | ||
|
|
||
|
|
||
|
|
@@ -97,8 +86,6 @@ struct _ceval_runtime_state { | |
| /* Pending calls to be made only on the main thread. */ | ||
| // The signal machinery falls back on this | ||
| // so it must be especially stable and efficient. | ||
| // For example, we use a preallocated array | ||
| // for the list of pending calls. | ||
|
Comment on lines
-100
to
-101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This point is still valid. |
||
| struct _pending_calls pending_mainthread; | ||
| PyMutex sys_trace_profile_mutex; | ||
| }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This point is still valid, so we should probably leave nearly all of the "main" pending calls stuff alone.