-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
gh-131253: free-threaded build support for pystats #137189
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
Changes from 12 commits
1c194e2
7dc9191
60454a2
df1c5d4
c94e5c4
e77af2c
488f0be
a48c7f6
612ea96
0e09267
a3cfb7e
724b086
bef1bcb
5034375
af9d886
09011fe
1e5db7a
873d915
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 |
|---|---|---|
|
|
@@ -217,6 +217,15 @@ struct _ts { | |
| */ | ||
| PyObject *threading_local_sentinel; | ||
| _PyRemoteDebuggerSupport remote_debugger_support; | ||
|
|
||
| #ifdef Py_STATS | ||
| // Pointer PyStats structure, NULL if recording is off. For the | ||
| // free-threaded build, the structure is per-thread (stored as a pointer | ||
| // in _PyThreadStateImpl). For the default build, the structure is stored | ||
| // in the PyInterpreterState structure (threads do not have their own | ||
| // structure and all share the same per-interpreter structure). | ||
| PyStats *pystats; | ||
| #endif | ||
| }; | ||
|
|
||
| /* other API */ | ||
|
|
@@ -239,6 +248,21 @@ PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); | |
| // function is set, otherwise disable them. | ||
| PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate); | ||
|
|
||
| #ifdef Py_STATS | ||
| #if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE) | ||
|
Contributor
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. With #140690,
Member
Author
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 think it's still needed. In pycore_pystate.h we have: I could change the code to: But I don't think that's better. |
||
| extern _Py_thread_local PyThreadState* _Py_tss_tstate; | ||
nascheme marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| static inline PyStats* | ||
nascheme marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| _PyThreadState_GetStatsFast(void) | ||
| { | ||
| if (_Py_tss_tstate == NULL) { | ||
|
Contributor
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 think you should be able to use
Member
Author
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 don't want I could potentially use |
||
| return NULL; // no attached thread state | ||
| } | ||
| return _Py_tss_tstate->pystats; | ||
| } | ||
| #endif | ||
| #endif // Py_STATS | ||
|
|
||
| /* PyGILState */ | ||
|
|
||
| /* Helper/diagnostic function - return 1 if the current thread | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ | |
| // | ||
| // - _Py_INCREF_STAT_INC() and _Py_DECREF_STAT_INC() used by Py_INCREF() | ||
| // and Py_DECREF(). | ||
| // - _Py_stats variable | ||
| // - _PyStats_GET() | ||
| // | ||
| // Functions of the sys module: | ||
| // | ||
|
|
@@ -14,7 +14,7 @@ | |
| // - sys._stats_dump() | ||
| // | ||
| // Python must be built with ./configure --enable-pystats to define the | ||
| // Py_STATS macro. | ||
| // _PyStats_GET() macro. | ||
| // | ||
| // Define _PY_INTERPRETER macro to increment interpreter_increfs and | ||
| // interpreter_decrefs. Otherwise, increment increfs and decrefs. | ||
|
|
@@ -109,6 +109,18 @@ typedef struct _gc_stats { | |
| uint64_t objects_not_transitively_reachable; | ||
| } GCStats; | ||
|
|
||
| #ifdef Py_GIL_DISABLED | ||
| // stats specific to free-threaded build | ||
| typedef struct _ft_stats { | ||
| // number of times interpreter had to spin or park when trying to acquire a mutex | ||
| uint64_t mutex_sleeps; | ||
| // number of times that the QSBR mechanism polled (compute read sequence value) | ||
| uint64_t qsbr_polls; | ||
| // number of times stop-the-world mechanism was used | ||
| uint64_t world_stops; | ||
markshannon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } FTStats; | ||
| #endif | ||
|
|
||
| typedef struct _uop_stats { | ||
| uint64_t execution_count; | ||
| uint64_t miss; | ||
|
|
@@ -173,22 +185,48 @@ typedef struct _stats { | |
| CallStats call_stats; | ||
| ObjectStats object_stats; | ||
| OptimizationStats optimization_stats; | ||
| #ifdef Py_GIL_DISABLED | ||
| FTStats ft_stats; | ||
| #endif | ||
| RareEventStats rare_event_stats; | ||
| GCStats *gc_stats; | ||
| GCStats gc_stats[3]; // must match NUM_GENERATIONS | ||
| } PyStats; | ||
|
|
||
| // Export for most shared extensions | ||
| PyAPI_FUNC(PyStats *) _PyStats_GetLocal(void); | ||
|
|
||
| #if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE) | ||
|
Contributor
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. Same |
||
| // use inline function version defined in cpython/pystate.h | ||
| static inline PyStats* _PyThreadState_GetStatsFast(void); | ||
| #define _PyStats_GET _PyThreadState_GetStatsFast | ||
| #else | ||
| #define _PyStats_GET _PyStats_GetLocal | ||
| #endif | ||
|
|
||
| // Export for shared extensions like 'math' | ||
| PyAPI_DATA(PyStats*) _Py_stats; | ||
| #define _Py_STATS_EXPR(expr) \ | ||
| do { \ | ||
| PyStats *s = _PyStats_GET(); \ | ||
| if (s != NULL) { \ | ||
| s->expr; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #define _Py_STATS_COND_EXPR(cond, expr) \ | ||
| do { \ | ||
| PyStats *s = _PyStats_GET(); \ | ||
| if (s != NULL && (cond)) { \ | ||
| s->expr; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #ifdef _PY_INTERPRETER | ||
| # define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_increfs++; } while (0) | ||
| # define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_decrefs++; } while (0) | ||
| # define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_increfs++; } while (0) | ||
| # define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_decrefs++; } while (0) | ||
| # define _Py_INCREF_STAT_INC() _Py_STATS_EXPR(object_stats.interpreter_increfs++) | ||
| # define _Py_DECREF_STAT_INC() _Py_STATS_EXPR(object_stats.interpreter_decrefs++) | ||
| # define _Py_INCREF_IMMORTAL_STAT_INC() _Py_STATS_EXPR(object_stats.interpreter_immortal_increfs++) | ||
| # define _Py_DECREF_IMMORTAL_STAT_INC() _Py_STATS_EXPR(object_stats.interpreter_immortal_decrefs++) | ||
| #else | ||
| # define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.increfs++; } while (0) | ||
| # define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.decrefs++; } while (0) | ||
| # define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_increfs++; } while (0) | ||
| # define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_decrefs++; } while (0) | ||
| # define _Py_INCREF_STAT_INC() _Py_STATS_EXPR(object_stats.increfs++) | ||
| # define _Py_DECREF_STAT_INC() _Py_STATS_EXPR(object_stats.decrefs++) | ||
| # define _Py_INCREF_IMMORTAL_STAT_INC() _Py_STATS_EXPR(object_stats.immortal_increfs++) | ||
| # define _Py_DECREF_IMMORTAL_STAT_INC() _Py_STATS_EXPR(object_stats.immortal_decrefs++) | ||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Support the ``--enable-pystats`` build option for the free-threaded build. |
Uh oh!
There was an error while loading. Please reload this page.