Skip to content
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

gh-110481: Implement biased reference counting #110764

Merged
merged 8 commits into from
Oct 30, 2023

Conversation

colesbury
Copy link
Contributor

@colesbury colesbury commented Oct 12, 2023

CPython's current reference counting implementation would not be thread-safe without the GIL. This implements biased reference counting in --disable-gil builds, which is thread-safe and has lower execution overhead compared to plain atomic reference counting. The design is described in the "Biased Reference Counting" section of PEP 703.

@colesbury
Copy link
Contributor Author

Note for reviewer: the first commit in this PR refactors the internal-only _PyObject_HEAD_INIT macro to not have a trailing comma, which avoids the need for a number of #ifdef Py_NOGIL in the subsequent commit.

@rhettinger rhettinger removed their request for review October 13, 2023 00:28
@corona10 corona10 self-requested a review October 17, 2023 15:36
@colesbury
Copy link
Contributor Author

@vstinner, will you have time to look at this PR this week?

@corona10
Copy link
Member

I read your PEP and related papers, so I can review for specific implementation of your works. I will leave review for this PR in this week :)

}
#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n)

static inline void _Py_SetImmortal(PyObject *op)
{
if (op) {
#ifdef Py_NOGIL
op->ob_tid = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we declare the constant variable for this? Something like UNKNOWN_TID?
I mean if someone already read the PEP, the person knows what the state that tid is zero stands for, but if not some kind of variable name will be helpful to read.

But I am not sure which will be the best naming

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've named it _Py_UNOWNED_TID because these are objects that are not owned by any thread.

Include/object.h Outdated Show resolved Hide resolved
Include/object.h Outdated
// zero. The call will deallocate the object if the shared refcount is also
// zero. Otherwise, the thread gives up ownership and merges the reference
// count fields.
PyAPI_FUNC(void) _Py_MergeZeroRefcount(PyObject *);
Copy link
Member

@corona10 corona10 Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I read the code, the purpose of this function is to handle the object when the local ref count is zero.
So might be, we can improve function name to understand what's happening

Suggested change
PyAPI_FUNC(void) _Py_MergeZeroRefcount(PyObject *);
PyAPI_FUNC(void) _Py_MergeZeroRefLocalcount(PyObject *);

or

Suggested change
PyAPI_FUNC(void) _Py_MergeZeroRefcount(PyObject *);
PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyObject *);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've named it _Py_MergeZeroLocalRefcount

Copy link
Member

@corona10 corona10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me.
I just leave the styling things for other readers.
IMO, It will help to understand the mechanism between local refcount and shared ref count.

Py_ssize_t
_Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra)
{
Py_ssize_t refcnt;
Copy link
Member

@corona10 corona10 Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, Don't we have to add assert statement that op should not be an immortal object?

assert(!_Py_IsImmortal(op));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good assertion to add.

Copy link
Contributor Author

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing this! I've updated the PR and rebased on the main branch.

}
#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n)

static inline void _Py_SetImmortal(PyObject *op)
{
if (op) {
#ifdef Py_NOGIL
op->ob_tid = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've named it _Py_UNOWNED_TID because these are objects that are not owned by any thread.

Include/object.h Outdated
// zero. The call will deallocate the object if the shared refcount is also
// zero. Otherwise, the thread gives up ownership and merges the reference
// count fields.
PyAPI_FUNC(void) _Py_MergeZeroRefcount(PyObject *);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've named it _Py_MergeZeroLocalRefcount

Py_ssize_t
_Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra)
{
Py_ssize_t refcnt;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good assertion to add.

Include/object.h Outdated Show resolved Hide resolved
@brettcannon brettcannon removed their request for review October 19, 2023 18:16
Copy link
Member

@corona10 corona10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colesbury In my macOS, the PR is failed to build :) Pleace check

9 warnings generated.
gcc  -fno-strict-overflow -Wsign-compare -Wunreachable-code -DNDEBUG -g -O3 -Wall    -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fvisibility=hidden  -I./Include/internal  -I. -I./Include     -c ./Modules/xxsubtype.c -o Modules/xxsubtype.o
In file included from ./Modules/_scproxy.c:9:
In file included from ./Include/Python.h:52:
./Include/object.h:276:22: error: implicit declaration of function '_Py_atomic_load_uint32_relaxed' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
                     ^
./Include/object.h:280:25: error: implicit declaration of function '_Py_atomic_load_ssize_relaxed' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
                        ^
./Include/object.h:280:25: note: did you mean '_Py_atomic_load_uint32_relaxed'?
./Include/object.h:276:22: note: '_Py_atomic_load_uint32_relaxed' declared here
    uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
                     ^
./Include/object.h:343:9: error: implicit declaration of function '_Py_IsOnwedByCurrentThread' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    if (_Py_IsOnwedByCurrentThread(ob)) {
        ^

Copy link
Member

@corona10 corona10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colesbury cc @vstinner @ambv
LGTM Again

Let's not block the PEP-703 works for the things.
It will not affect the default implementation, and for the limited C API issue, I believe that we can solve it before we want to use free-threaded mode by default.

Let's solve it as a separate issue.

@corona10 corona10 enabled auto-merge (squash) October 30, 2023 15:38
@corona10 corona10 merged commit 6dfb8fe into python:main Oct 30, 2023
32 checks passed
@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x Debian 3.x has failed when building commit 6dfb8fe.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/49/builds/7039) and take a look at the build logs.
  4. Check if the failure is related to this commit (6dfb8fe) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/49/builds/7039

Summary of the results of the build (if available):

Click to see traceback logs
remote: Enumerating objects: 96, done.        
remote: Counting objects:   1% (1/96)        
remote: Counting objects:   2% (2/96)        
remote: Counting objects:   3% (3/96)        
remote: Counting objects:   4% (4/96)        
remote: Counting objects:   5% (5/96)        
remote: Counting objects:   6% (6/96)        
remote: Counting objects:   7% (7/96)        
remote: Counting objects:   8% (8/96)        
remote: Counting objects:   9% (9/96)        
remote: Counting objects:  10% (10/96)        
remote: Counting objects:  11% (11/96)        
remote: Counting objects:  12% (12/96)        
remote: Counting objects:  13% (13/96)        
remote: Counting objects:  14% (14/96)        
remote: Counting objects:  15% (15/96)        
remote: Counting objects:  16% (16/96)        
remote: Counting objects:  17% (17/96)        
remote: Counting objects:  18% (18/96)        
remote: Counting objects:  19% (19/96)        
remote: Counting objects:  20% (20/96)        
remote: Counting objects:  21% (21/96)        
remote: Counting objects:  22% (22/96)        
remote: Counting objects:  23% (23/96)        
remote: Counting objects:  25% (24/96)        
remote: Counting objects:  26% (25/96)        
remote: Counting objects:  27% (26/96)        
remote: Counting objects:  28% (27/96)        
remote: Counting objects:  29% (28/96)        
remote: Counting objects:  30% (29/96)        
remote: Counting objects:  31% (30/96)        
remote: Counting objects:  32% (31/96)        
remote: Counting objects:  33% (32/96)        
remote: Counting objects:  34% (33/96)        
remote: Counting objects:  35% (34/96)        
remote: Counting objects:  36% (35/96)        
remote: Counting objects:  37% (36/96)        
remote: Counting objects:  38% (37/96)        
remote: Counting objects:  39% (38/96)        
remote: Counting objects:  40% (39/96)        
remote: Counting objects:  41% (40/96)        
remote: Counting objects:  42% (41/96)        
remote: Counting objects:  43% (42/96)        
remote: Counting objects:  44% (43/96)        
remote: Counting objects:  45% (44/96)        
remote: Counting objects:  46% (45/96)        
remote: Counting objects:  47% (46/96)        
remote: Counting objects:  48% (47/96)        
remote: Counting objects:  50% (48/96)        
remote: Counting objects:  51% (49/96)        
remote: Counting objects:  52% (50/96)        
remote: Counting objects:  53% (51/96)        
remote: Counting objects:  54% (52/96)        
remote: Counting objects:  55% (53/96)        
remote: Counting objects:  56% (54/96)        
remote: Counting objects:  57% (55/96)        
remote: Counting objects:  58% (56/96)        
remote: Counting objects:  59% (57/96)        
remote: Counting objects:  60% (58/96)        
remote: Counting objects:  61% (59/96)        
remote: Counting objects:  62% (60/96)        
remote: Counting objects:  63% (61/96)        
remote: Counting objects:  64% (62/96)        
remote: Counting objects:  65% (63/96)        
remote: Counting objects:  66% (64/96)        
remote: Counting objects:  67% (65/96)        
remote: Counting objects:  68% (66/96)        
remote: Counting objects:  69% (67/96)        
remote: Counting objects:  70% (68/96)        
remote: Counting objects:  71% (69/96)        
remote: Counting objects:  72% (70/96)        
remote: Counting objects:  73% (71/96)        
remote: Counting objects:  75% (72/96)        
remote: Counting objects:  76% (73/96)        
remote: Counting objects:  77% (74/96)        
remote: Counting objects:  78% (75/96)        
remote: Counting objects:  79% (76/96)        
remote: Counting objects:  80% (77/96)        
remote: Counting objects:  81% (78/96)        
remote: Counting objects:  82% (79/96)        
remote: Counting objects:  83% (80/96)        
remote: Counting objects:  84% (81/96)        
remote: Counting objects:  85% (82/96)        
remote: Counting objects:  86% (83/96)        
remote: Counting objects:  87% (84/96)        
remote: Counting objects:  88% (85/96)        
remote: Counting objects:  89% (86/96)        
remote: Counting objects:  90% (87/96)        
remote: Counting objects:  91% (88/96)        
remote: Counting objects:  92% (89/96)        
remote: Counting objects:  93% (90/96)        
remote: Counting objects:  94% (91/96)        
remote: Counting objects:  95% (92/96)        
remote: Counting objects:  96% (93/96)        
remote: Counting objects:  97% (94/96)        
remote: Counting objects:  98% (95/96)        
remote: Counting objects: 100% (96/96)        
remote: Counting objects: 100% (96/96), done.        
remote: Compressing objects:   2% (1/42)        
remote: Compressing objects:   4% (2/42)        
remote: Compressing objects:   7% (3/42)        
remote: Compressing objects:   9% (4/42)        
remote: Compressing objects:  11% (5/42)        
remote: Compressing objects:  14% (6/42)        
remote: Compressing objects:  16% (7/42)        
remote: Compressing objects:  19% (8/42)        
remote: Compressing objects:  21% (9/42)        
remote: Compressing objects:  23% (10/42)        
remote: Compressing objects:  26% (11/42)        
remote: Compressing objects:  28% (12/42)        
remote: Compressing objects:  30% (13/42)        
remote: Compressing objects:  33% (14/42)        
remote: Compressing objects:  35% (15/42)        
remote: Compressing objects:  38% (16/42)        
remote: Compressing objects:  40% (17/42)        
remote: Compressing objects:  42% (18/42)        
remote: Compressing objects:  45% (19/42)        
remote: Compressing objects:  47% (20/42)        
remote: Compressing objects:  50% (21/42)        
remote: Compressing objects:  52% (22/42)        
remote: Compressing objects:  54% (23/42)        
remote: Compressing objects:  57% (24/42)        
remote: Compressing objects:  59% (25/42)        
remote: Compressing objects:  61% (26/42)        
remote: Compressing objects:  64% (27/42)        
remote: Compressing objects:  66% (28/42)        
remote: Compressing objects:  69% (29/42)        
remote: Compressing objects:  71% (30/42)        
remote: Compressing objects:  73% (31/42)        
remote: Compressing objects:  76% (32/42)        
remote: Compressing objects:  78% (33/42)        
remote: Compressing objects:  80% (34/42)        
remote: Compressing objects:  83% (35/42)        
remote: Compressing objects:  85% (36/42)        
remote: Compressing objects:  88% (37/42)        
remote: Compressing objects:  90% (38/42)        
remote: Compressing objects:  92% (39/42)        
remote: Compressing objects:  95% (40/42)        
remote: Compressing objects:  97% (41/42)        
remote: Compressing objects: 100% (42/42)        
remote: Compressing objects: 100% (42/42), done.        
remote: Total 49 (delta 47), reused 8 (delta 7), pack-reused 0        
From https://github.com/python/cpython
 * branch                  main       -> FETCH_HEAD
Note: switching to '6dfb8fe0236718e9afc8136ff2b58dcfbc182022'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 6dfb8fe023 gh-110481: Implement biased reference counting (gh-110764)
Switched to and reset branch 'main'

In file included from ./Include/Python.h:52,
                 from Parser/token.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
In file included from ./Include/Python.h:52,
                 from Parser/pegen.h:4,
                 from Parser/parser.c:2:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
In file included from ./Include/Python.h:52,
                 from ./Programs/python.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
make: *** [Makefile:2757: Parser/token.o] Error 1
make: *** Waiting for unfinished jobs....
In file included from ./Include/Python.h:52,
                 from Parser/pegen.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
make: *** [Makefile:1530: Programs/python.o] Error 1
In file included from ./Include/Python.h:52,
                 from Parser/pegen_errors.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
In file included from ./Include/Python.h:52,
                 from Parser/action_helpers.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
  258 |   # error "define _Py_ThreadId for this platform"
      |     ^~~~~
make: *** [Makefile:2757: Parser/pegen_errors.o] Error 1
make: *** [Makefile:2757: Parser/pegen.o] Error 1
make: *** [Makefile:2757: Parser/action_helpers.o] Error 1
make: *** [Makefile:2757: Parser/parser.o] Error 1

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [Makefile:2849: clean-retain-profile] Error 1 (ignored)

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x RHEL7 3.x has failed when building commit 6dfb8fe.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/179/builds/5821) and take a look at the build logs.
  4. Check if the failure is related to this commit (6dfb8fe) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/179/builds/5821

Summary of the results of the build (if available):

Click to see traceback logs
remote: Enumerating objects: 96, done.�[K
remote: Counting objects:   1% (1/96)�[K
remote: Counting objects:   2% (2/96)�[K
remote: Counting objects:   3% (3/96)�[K
remote: Counting objects:   4% (4/96)�[K
remote: Counting objects:   5% (5/96)�[K
remote: Counting objects:   6% (6/96)�[K
remote: Counting objects:   7% (7/96)�[K
remote: Counting objects:   8% (8/96)�[K
remote: Counting objects:   9% (9/96)�[K
remote: Counting objects:  10% (10/96)�[K
remote: Counting objects:  11% (11/96)�[K
remote: Counting objects:  12% (12/96)�[K
remote: Counting objects:  13% (13/96)�[K
remote: Counting objects:  14% (14/96)�[K
remote: Counting objects:  15% (15/96)�[K
remote: Counting objects:  16% (16/96)�[K
remote: Counting objects:  17% (17/96)�[K
remote: Counting objects:  18% (18/96)�[K
remote: Counting objects:  19% (19/96)�[K
remote: Counting objects:  20% (20/96)�[K
remote: Counting objects:  21% (21/96)�[K
remote: Counting objects:  22% (22/96)�[K
remote: Counting objects:  23% (23/96)�[K
remote: Counting objects:  25% (24/96)�[K
remote: Counting objects:  26% (25/96)�[K
remote: Counting objects:  27% (26/96)�[K
remote: Counting objects:  28% (27/96)�[K
remote: Counting objects:  29% (28/96)�[K
remote: Counting objects:  30% (29/96)�[K
remote: Counting objects:  31% (30/96)�[K
remote: Counting objects:  32% (31/96)�[K
remote: Counting objects:  33% (32/96)�[K
remote: Counting objects:  34% (33/96)�[K
remote: Counting objects:  35% (34/96)�[K
remote: Counting objects:  36% (35/96)�[K
remote: Counting objects:  37% (36/96)�[K
remote: Counting objects:  38% (37/96)�[K
remote: Counting objects:  39% (38/96)�[K
remote: Counting objects:  40% (39/96)�[K
remote: Counting objects:  41% (40/96)�[K
remote: Counting objects:  42% (41/96)�[K
remote: Counting objects:  43% (42/96)�[K
remote: Counting objects:  44% (43/96)�[K
remote: Counting objects:  45% (44/96)�[K
remote: Counting objects:  46% (45/96)�[K
remote: Counting objects:  47% (46/96)�[K
remote: Counting objects:  48% (47/96)�[K
remote: Counting objects:  50% (48/96)�[K
remote: Counting objects:  51% (49/96)�[K
remote: Counting objects:  52% (50/96)�[K
remote: Counting objects:  53% (51/96)�[K
remote: Counting objects:  54% (52/96)�[K
remote: Counting objects:  55% (53/96)�[K
remote: Counting objects:  56% (54/96)�[K
remote: Counting objects:  57% (55/96)�[K
remote: Counting objects:  58% (56/96)�[K
remote: Counting objects:  59% (57/96)�[K
remote: Counting objects:  60% (58/96)�[K
remote: Counting objects:  61% (59/96)�[K
remote: Counting objects:  62% (60/96)�[K
remote: Counting objects:  63% (61/96)�[K
remote: Counting objects:  64% (62/96)�[K
remote: Counting objects:  65% (63/96)�[K
remote: Counting objects:  66% (64/96)�[K
remote: Counting objects:  67% (65/96)�[K
remote: Counting objects:  68% (66/96)�[K
remote: Counting objects:  69% (67/96)�[K
remote: Counting objects:  70% (68/96)�[K
remote: Counting objects:  71% (69/96)�[K
remote: Counting objects:  72% (70/96)�[K
remote: Counting objects:  73% (71/96)�[K
remote: Counting objects:  75% (72/96)�[K
remote: Counting objects:  76% (73/96)�[K
remote: Counting objects:  77% (74/96)�[K
remote: Counting objects:  78% (75/96)�[K
remote: Counting objects:  79% (76/96)�[K
remote: Counting objects:  80% (77/96)�[K
remote: Counting objects:  81% (78/96)�[K
remote: Counting objects:  82% (79/96)�[K
remote: Counting objects:  83% (80/96)�[K
remote: Counting objects:  84% (81/96)�[K
remote: Counting objects:  85% (82/96)�[K
remote: Counting objects:  86% (83/96)�[K
remote: Counting objects:  87% (84/96)�[K
remote: Counting objects:  88% (85/96)�[K
remote: Counting objects:  89% (86/96)�[K
remote: Counting objects:  90% (87/96)�[K
remote: Counting objects:  91% (88/96)�[K
remote: Counting objects:  92% (89/96)�[K
remote: Counting objects:  93% (90/96)�[K
remote: Counting objects:  94% (91/96)�[K
remote: Counting objects:  95% (92/96)�[K
remote: Counting objects:  96% (93/96)�[K
remote: Counting objects:  97% (94/96)�[K
remote: Counting objects:  98% (95/96)�[K
remote: Counting objects: 100% (96/96)�[K
remote: Counting objects: 100% (96/96), done.�[K
remote: Compressing objects:   2% (1/42)�[K
remote: Compressing objects:   4% (2/42)�[K
remote: Compressing objects:   7% (3/42)�[K
remote: Compressing objects:   9% (4/42)�[K
remote: Compressing objects:  11% (5/42)�[K
remote: Compressing objects:  14% (6/42)�[K
remote: Compressing objects:  16% (7/42)�[K
remote: Compressing objects:  19% (8/42)�[K
remote: Compressing objects:  21% (9/42)�[K
remote: Compressing objects:  23% (10/42)�[K
remote: Compressing objects:  26% (11/42)�[K
remote: Compressing objects:  28% (12/42)�[K
remote: Compressing objects:  30% (13/42)�[K
remote: Compressing objects:  33% (14/42)�[K
remote: Compressing objects:  35% (15/42)�[K
remote: Compressing objects:  38% (16/42)�[K
remote: Compressing objects:  40% (17/42)�[K
remote: Compressing objects:  42% (18/42)�[K
remote: Compressing objects:  45% (19/42)�[K
remote: Compressing objects:  47% (20/42)�[K
remote: Compressing objects:  50% (21/42)�[K
remote: Compressing objects:  52% (22/42)�[K
remote: Compressing objects:  54% (23/42)�[K
remote: Compressing objects:  57% (24/42)�[K
remote: Compressing objects:  59% (25/42)�[K
remote: Compressing objects:  61% (26/42)�[K
remote: Compressing objects:  64% (27/42)�[K
remote: Compressing objects:  66% (28/42)�[K
remote: Compressing objects:  69% (29/42)�[K
remote: Compressing objects:  71% (30/42)�[K
remote: Compressing objects:  73% (31/42)�[K
remote: Compressing objects:  76% (32/42)�[K
remote: Compressing objects:  78% (33/42)�[K
remote: Compressing objects:  80% (34/42)�[K
remote: Compressing objects:  83% (35/42)�[K
remote: Compressing objects:  85% (36/42)�[K
remote: Compressing objects:  88% (37/42)�[K
remote: Compressing objects:  90% (38/42)�[K
remote: Compressing objects:  92% (39/42)�[K
remote: Compressing objects:  95% (40/42)�[K
remote: Compressing objects:  97% (41/42)�[K
remote: Compressing objects: 100% (42/42)�[K
remote: Compressing objects: 100% (42/42), done.�[K
remote: Total 49 (delta 47), reused 8 (delta 7), pack-reused 0�[K
From https://github.com/python/cpython
 * branch            main       -> FETCH_HEAD
Note: checking out '6dfb8fe0236718e9afc8136ff2b58dcfbc182022'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 6dfb8fe... gh-110481: Implement biased reference counting (gh-110764)
Switched to and reset branch 'main'

In file included from ./Include/Python.h:52:0,
                 from Parser/token.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from ./Programs/python.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.h:4,
                 from Parser/parser.c:2:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
make: *** [Parser/token.o] Error 1
make: *** Waiting for unfinished jobs....
In file included from ./Include/Python.h:52:0,
                 from Parser/action_helpers.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen_errors.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
make: *** [Programs/python.o] Error 1
make: *** [Parser/pegen.o] Error 1
make: *** [Parser/pegen_errors.o] Error 1
make: *** [Parser/action_helpers.o] Error 1
make: *** [Parser/parser.o] Error 1

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [clean-retain-profile] Error 1 (ignored)

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x SLES 3.x has failed when building commit 6dfb8fe.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/540/builds/7003) and take a look at the build logs.
  4. Check if the failure is related to this commit (6dfb8fe) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/540/builds/7003

Summary of the results of the build (if available):

Click to see traceback logs
remote: Enumerating objects: 96, done.        
remote: Counting objects:   1% (1/96)        
remote: Counting objects:   2% (2/96)        
remote: Counting objects:   3% (3/96)        
remote: Counting objects:   4% (4/96)        
remote: Counting objects:   5% (5/96)        
remote: Counting objects:   6% (6/96)        
remote: Counting objects:   7% (7/96)        
remote: Counting objects:   8% (8/96)        
remote: Counting objects:   9% (9/96)        
remote: Counting objects:  10% (10/96)        
remote: Counting objects:  11% (11/96)        
remote: Counting objects:  12% (12/96)        
remote: Counting objects:  13% (13/96)        
remote: Counting objects:  14% (14/96)        
remote: Counting objects:  15% (15/96)        
remote: Counting objects:  16% (16/96)        
remote: Counting objects:  17% (17/96)        
remote: Counting objects:  18% (18/96)        
remote: Counting objects:  19% (19/96)        
remote: Counting objects:  20% (20/96)        
remote: Counting objects:  21% (21/96)        
remote: Counting objects:  22% (22/96)        
remote: Counting objects:  23% (23/96)        
remote: Counting objects:  25% (24/96)        
remote: Counting objects:  26% (25/96)        
remote: Counting objects:  27% (26/96)        
remote: Counting objects:  28% (27/96)        
remote: Counting objects:  29% (28/96)        
remote: Counting objects:  30% (29/96)        
remote: Counting objects:  31% (30/96)        
remote: Counting objects:  32% (31/96)        
remote: Counting objects:  33% (32/96)        
remote: Counting objects:  34% (33/96)        
remote: Counting objects:  35% (34/96)        
remote: Counting objects:  36% (35/96)        
remote: Counting objects:  37% (36/96)        
remote: Counting objects:  38% (37/96)        
remote: Counting objects:  39% (38/96)        
remote: Counting objects:  40% (39/96)        
remote: Counting objects:  41% (40/96)        
remote: Counting objects:  42% (41/96)        
remote: Counting objects:  43% (42/96)        
remote: Counting objects:  44% (43/96)        
remote: Counting objects:  45% (44/96)        
remote: Counting objects:  46% (45/96)        
remote: Counting objects:  47% (46/96)        
remote: Counting objects:  48% (47/96)        
remote: Counting objects:  50% (48/96)        
remote: Counting objects:  51% (49/96)        
remote: Counting objects:  52% (50/96)        
remote: Counting objects:  53% (51/96)        
remote: Counting objects:  54% (52/96)        
remote: Counting objects:  55% (53/96)        
remote: Counting objects:  56% (54/96)        
remote: Counting objects:  57% (55/96)        
remote: Counting objects:  58% (56/96)        
remote: Counting objects:  59% (57/96)        
remote: Counting objects:  60% (58/96)        
remote: Counting objects:  61% (59/96)        
remote: Counting objects:  62% (60/96)        
remote: Counting objects:  63% (61/96)        
remote: Counting objects:  64% (62/96)        
remote: Counting objects:  65% (63/96)        
remote: Counting objects:  66% (64/96)        
remote: Counting objects:  67% (65/96)        
remote: Counting objects:  68% (66/96)        
remote: Counting objects:  69% (67/96)        
remote: Counting objects:  70% (68/96)        
remote: Counting objects:  71% (69/96)        
remote: Counting objects:  72% (70/96)        
remote: Counting objects:  73% (71/96)        
remote: Counting objects:  75% (72/96)        
remote: Counting objects:  76% (73/96)        
remote: Counting objects:  77% (74/96)        
remote: Counting objects:  78% (75/96)        
remote: Counting objects:  79% (76/96)        
remote: Counting objects:  80% (77/96)        
remote: Counting objects:  81% (78/96)        
remote: Counting objects:  82% (79/96)        
remote: Counting objects:  83% (80/96)        
remote: Counting objects:  84% (81/96)        
remote: Counting objects:  85% (82/96)        
remote: Counting objects:  86% (83/96)        
remote: Counting objects:  87% (84/96)        
remote: Counting objects:  88% (85/96)        
remote: Counting objects:  89% (86/96)        
remote: Counting objects:  90% (87/96)        
remote: Counting objects:  91% (88/96)        
remote: Counting objects:  92% (89/96)        
remote: Counting objects:  93% (90/96)        
remote: Counting objects:  94% (91/96)        
remote: Counting objects:  95% (92/96)        
remote: Counting objects:  96% (93/96)        
remote: Counting objects:  97% (94/96)        
remote: Counting objects:  98% (95/96)        
remote: Counting objects: 100% (96/96)        
remote: Counting objects: 100% (96/96), done.        
remote: Compressing objects:   2% (1/42)        
remote: Compressing objects:   4% (2/42)        
remote: Compressing objects:   7% (3/42)        
remote: Compressing objects:   9% (4/42)        
remote: Compressing objects:  11% (5/42)        
remote: Compressing objects:  14% (6/42)        
remote: Compressing objects:  16% (7/42)        
remote: Compressing objects:  19% (8/42)        
remote: Compressing objects:  21% (9/42)        
remote: Compressing objects:  23% (10/42)        
remote: Compressing objects:  26% (11/42)        
remote: Compressing objects:  28% (12/42)        
remote: Compressing objects:  30% (13/42)        
remote: Compressing objects:  33% (14/42)        
remote: Compressing objects:  35% (15/42)        
remote: Compressing objects:  38% (16/42)        
remote: Compressing objects:  40% (17/42)        
remote: Compressing objects:  42% (18/42)        
remote: Compressing objects:  45% (19/42)        
remote: Compressing objects:  47% (20/42)        
remote: Compressing objects:  50% (21/42)        
remote: Compressing objects:  52% (22/42)        
remote: Compressing objects:  54% (23/42)        
remote: Compressing objects:  57% (24/42)        
remote: Compressing objects:  59% (25/42)        
remote: Compressing objects:  61% (26/42)        
remote: Compressing objects:  64% (27/42)        
remote: Compressing objects:  66% (28/42)        
remote: Compressing objects:  69% (29/42)        
remote: Compressing objects:  71% (30/42)        
remote: Compressing objects:  73% (31/42)        
remote: Compressing objects:  76% (32/42)        
remote: Compressing objects:  78% (33/42)        
remote: Compressing objects:  80% (34/42)        
remote: Compressing objects:  83% (35/42)        
remote: Compressing objects:  85% (36/42)        
remote: Compressing objects:  88% (37/42)        
remote: Compressing objects:  90% (38/42)        
remote: Compressing objects:  92% (39/42)        
remote: Compressing objects:  95% (40/42)        
remote: Compressing objects:  97% (41/42)        
remote: Compressing objects: 100% (42/42)        
remote: Compressing objects: 100% (42/42), done.        
remote: Total 49 (delta 47), reused 8 (delta 7), pack-reused 0        
From https://github.com/python/cpython
 * branch                  main       -> FETCH_HEAD
Note: switching to '6dfb8fe0236718e9afc8136ff2b58dcfbc182022'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 6dfb8fe023 gh-110481: Implement biased reference counting (gh-110764)
Switched to and reset branch 'main'

In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
In file included from ./Include/Python.h:52:0,
                 from ./Programs/python.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
In file included from ./Include/Python.h:52:0,
                 from Parser/token.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
In file included from ./Include/Python.h:52:0,
                 from Parser/action_helpers.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
make: *** [Makefile:1527: Programs/python.o] Error 1
make: *** Waiting for unfinished jobs....
make: *** [Makefile:2754: Parser/token.o] Error 1
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.h:4,
                 from Parser/parser.c:2:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
make: *** [Makefile:2754: Parser/pegen.o] Error 1
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen_errors.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^~~~~
make: *** [Makefile:2754: Parser/action_helpers.o] Error 1
make: *** [Makefile:2754: Parser/pegen_errors.o] Error 1
make: *** [Makefile:2754: Parser/parser.o] Error 1

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [Makefile:2846: clean-retain-profile] Error 1 (ignored)

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x RHEL7 LTO + PGO 3.x has failed when building commit 6dfb8fe.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/244/builds/5777) and take a look at the build logs.
  4. Check if the failure is related to this commit (6dfb8fe) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/244/builds/5777

Summary of the results of the build (if available):

Click to see traceback logs
remote: Enumerating objects: 96, done.�[K
remote: Counting objects:   1% (1/96)�[K
remote: Counting objects:   2% (2/96)�[K
remote: Counting objects:   3% (3/96)�[K
remote: Counting objects:   4% (4/96)�[K
remote: Counting objects:   5% (5/96)�[K
remote: Counting objects:   6% (6/96)�[K
remote: Counting objects:   7% (7/96)�[K
remote: Counting objects:   8% (8/96)�[K
remote: Counting objects:   9% (9/96)�[K
remote: Counting objects:  10% (10/96)�[K
remote: Counting objects:  11% (11/96)�[K
remote: Counting objects:  12% (12/96)�[K
remote: Counting objects:  13% (13/96)�[K
remote: Counting objects:  14% (14/96)�[K
remote: Counting objects:  15% (15/96)�[K
remote: Counting objects:  16% (16/96)�[K
remote: Counting objects:  17% (17/96)�[K
remote: Counting objects:  18% (18/96)�[K
remote: Counting objects:  19% (19/96)�[K
remote: Counting objects:  20% (20/96)�[K
remote: Counting objects:  21% (21/96)�[K
remote: Counting objects:  22% (22/96)�[K
remote: Counting objects:  23% (23/96)�[K
remote: Counting objects:  25% (24/96)�[K
remote: Counting objects:  26% (25/96)�[K
remote: Counting objects:  27% (26/96)�[K
remote: Counting objects:  28% (27/96)�[K
remote: Counting objects:  29% (28/96)�[K
remote: Counting objects:  30% (29/96)�[K
remote: Counting objects:  31% (30/96)�[K
remote: Counting objects:  32% (31/96)�[K
remote: Counting objects:  33% (32/96)�[K
remote: Counting objects:  34% (33/96)�[K
remote: Counting objects:  35% (34/96)�[K
remote: Counting objects:  36% (35/96)�[K
remote: Counting objects:  37% (36/96)�[K
remote: Counting objects:  38% (37/96)�[K
remote: Counting objects:  39% (38/96)�[K
remote: Counting objects:  40% (39/96)�[K
remote: Counting objects:  41% (40/96)�[K
remote: Counting objects:  42% (41/96)�[K
remote: Counting objects:  43% (42/96)�[K
remote: Counting objects:  44% (43/96)�[K
remote: Counting objects:  45% (44/96)�[K
remote: Counting objects:  46% (45/96)�[K
remote: Counting objects:  47% (46/96)�[K
remote: Counting objects:  48% (47/96)�[K
remote: Counting objects:  50% (48/96)�[K
remote: Counting objects:  51% (49/96)�[K
remote: Counting objects:  52% (50/96)�[K
remote: Counting objects:  53% (51/96)�[K
remote: Counting objects:  54% (52/96)�[K
remote: Counting objects:  55% (53/96)�[K
remote: Counting objects:  56% (54/96)�[K
remote: Counting objects:  57% (55/96)�[K
remote: Counting objects:  58% (56/96)�[K
remote: Counting objects:  59% (57/96)�[K
remote: Counting objects:  60% (58/96)�[K
remote: Counting objects:  61% (59/96)�[K
remote: Counting objects:  62% (60/96)�[K
remote: Counting objects:  63% (61/96)�[K
remote: Counting objects:  64% (62/96)�[K
remote: Counting objects:  65% (63/96)�[K
remote: Counting objects:  66% (64/96)�[K
remote: Counting objects:  67% (65/96)�[K
remote: Counting objects:  68% (66/96)�[K
remote: Counting objects:  69% (67/96)�[K
remote: Counting objects:  70% (68/96)�[K
remote: Counting objects:  71% (69/96)�[K
remote: Counting objects:  72% (70/96)�[K
remote: Counting objects:  73% (71/96)�[K
remote: Counting objects:  75% (72/96)�[K
remote: Counting objects:  76% (73/96)�[K
remote: Counting objects:  77% (74/96)�[K
remote: Counting objects:  78% (75/96)�[K
remote: Counting objects:  79% (76/96)�[K
remote: Counting objects:  80% (77/96)�[K
remote: Counting objects:  81% (78/96)�[K
remote: Counting objects:  82% (79/96)�[K
remote: Counting objects:  83% (80/96)�[K
remote: Counting objects:  84% (81/96)�[K
remote: Counting objects:  85% (82/96)�[K
remote: Counting objects:  86% (83/96)�[K
remote: Counting objects:  87% (84/96)�[K
remote: Counting objects:  88% (85/96)�[K
remote: Counting objects:  89% (86/96)�[K
remote: Counting objects:  90% (87/96)�[K
remote: Counting objects:  91% (88/96)�[K
remote: Counting objects:  92% (89/96)�[K
remote: Counting objects:  93% (90/96)�[K
remote: Counting objects:  94% (91/96)�[K
remote: Counting objects:  95% (92/96)�[K
remote: Counting objects:  96% (93/96)�[K
remote: Counting objects:  97% (94/96)�[K
remote: Counting objects:  98% (95/96)�[K
remote: Counting objects: 100% (96/96)�[K
remote: Counting objects: 100% (96/96), done.�[K
remote: Compressing objects:   2% (1/42)�[K
remote: Compressing objects:   4% (2/42)�[K
remote: Compressing objects:   7% (3/42)�[K
remote: Compressing objects:   9% (4/42)�[K
remote: Compressing objects:  11% (5/42)�[K
remote: Compressing objects:  14% (6/42)�[K
remote: Compressing objects:  16% (7/42)�[K
remote: Compressing objects:  19% (8/42)�[K
remote: Compressing objects:  21% (9/42)�[K
remote: Compressing objects:  23% (10/42)�[K
remote: Compressing objects:  26% (11/42)�[K
remote: Compressing objects:  28% (12/42)�[K
remote: Compressing objects:  30% (13/42)�[K
remote: Compressing objects:  33% (14/42)�[K
remote: Compressing objects:  35% (15/42)�[K
remote: Compressing objects:  38% (16/42)�[K
remote: Compressing objects:  40% (17/42)�[K
remote: Compressing objects:  42% (18/42)�[K
remote: Compressing objects:  45% (19/42)�[K
remote: Compressing objects:  47% (20/42)�[K
remote: Compressing objects:  50% (21/42)�[K
remote: Compressing objects:  52% (22/42)�[K
remote: Compressing objects:  54% (23/42)�[K
remote: Compressing objects:  57% (24/42)�[K
remote: Compressing objects:  59% (25/42)�[K
remote: Compressing objects:  61% (26/42)�[K
remote: Compressing objects:  64% (27/42)�[K
remote: Compressing objects:  66% (28/42)�[K
remote: Compressing objects:  69% (29/42)�[K
remote: Compressing objects:  71% (30/42)�[K
remote: Compressing objects:  73% (31/42)�[K
remote: Compressing objects:  76% (32/42)�[K
remote: Compressing objects:  78% (33/42)�[K
remote: Compressing objects:  80% (34/42)�[K
remote: Compressing objects:  83% (35/42)�[K
remote: Compressing objects:  85% (36/42)�[K
remote: Compressing objects:  88% (37/42)�[K
remote: Compressing objects:  90% (38/42)�[K
remote: Compressing objects:  92% (39/42)�[K
remote: Compressing objects:  95% (40/42)�[K
remote: Compressing objects:  97% (41/42)�[K
remote: Compressing objects: 100% (42/42)�[K
remote: Compressing objects: 100% (42/42), done.�[K
remote: Total 49 (delta 47), reused 8 (delta 7), pack-reused 0�[K
From https://github.com/python/cpython
 * branch            main       -> FETCH_HEAD
Note: checking out '6dfb8fe0236718e9afc8136ff2b58dcfbc182022'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 6dfb8fe... gh-110481: Implement biased reference counting (gh-110764)
Switched to and reset branch 'main'

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make[2]: [clean-retain-profile] Error 1 (ignored)
In file included from ./Include/Python.h:52:0,
                 from ./Programs/python.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/token.c:3:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen_errors.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
make[2]: *** [Programs/python.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [Parser/pegen_errors.o] Error 1
make[2]: *** [Parser/token.o] Error 1
In file included from ./Include/Python.h:52:0,
                 from Parser/pegen.h:4,
                 from Parser/parser.c:2:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
In file included from ./Include/Python.h:52:0,
                 from Parser/action_helpers.c:1:
./Include/object.h: In function ‘_Py_ThreadId’:
./Include/object.h:258:5: error: #error "define _Py_ThreadId for this platform"
   # error "define _Py_ThreadId for this platform"
     ^
make[2]: *** [Parser/pegen.o] Error 1
make[2]: *** [Parser/action_helpers.o] Error 1
make[2]: *** [Parser/parser.o] Error 1
make[1]: *** [profile-gen-stamp] Error 2
make: *** [profile-run-stamp] Error 2

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [clean-retain-profile] Error 1 (ignored)

@corona10
Copy link
Member

For the build bot issue, please follow up: #111503

@vstinner
Copy link
Member

For the limited C API, I wrote a first change: PR #111505.

@vstinner
Copy link
Member

Congrats @colesbury, that's a massive change :-)

Comment on lines +251 to +257
#elif defined(__arm__)
__asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid));
#elif defined(__aarch64__) && defined(__APPLE__)
__asm__ ("mrs %0, tpidrro_el0" : "=r" (tid));
#elif defined(__aarch64__)
__asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
#else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caveat: I'm not an expert.
In case of x86/x86-64 above, the tid values has to be copied to a regular register for comparison.
In case of ARM32, the comparison could be made directly, were it not for the 2 lsb.
In case of ARM64, the comparison could be made directly.

Leaving aside the less common case of stamping the biased reference count block, and focusing on the more common case of comparing the current tid with object owner tid:

Does the compiler optimise this move away?
Does it perhaps not matter, as move is fast compared to loading the object's value from ram or cache?
Or would a custom comparison macro make sense here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is backwards: on x86/x86-64 you can do a comparison without copying tid to a register; you can't on ARM.

On x86, many instructions, such as cmp, can operate on memory addresses, including addresses with fs: or gs: prefixes. It doesn't matter much here because because the object's owner tid also requires a memory load. So either one or the other needs to be moved to a temporary registers and it's more convenient to move the current tid to a temporary register because it may be re-used across multiple reference count operations.

On ARM you can't do a comparison with a system or coprocessor register. You need to move it to a gpr first.

@mdboom
Copy link
Contributor

mdboom commented Oct 31, 2023

I ran this PR on the Faster CPython team's benchmarking infrastructure, and its effect is basically immeasurable, 1.00x slower with a reliability of 95%: https://github.com/faster-cpython/benchmarking-public/blob/main/results/bm-20231030-3.13.0a1%2B-6dfb8fe/bm-20231030-linux-x86_64-python-6dfb8fe0236718e9afc8-3.13.0a1%2B-6dfb8fe-vs-base.md

EDIT: As @ericsnowcurrently pointed out, this is with a default build, so is not terribly interesting. I'll rerun with --disable-gil and report back.

@vstinner
Copy link
Member

EDIT: As @ericsnowcurrently pointed out, this is with a default build, so is not terribly interesting.

This PR only impacts Python if Python is configured with --disable-gil.

@colesbury colesbury deleted the biased_reference_counting branch October 31, 2023 18:58
@mdboom
Copy link
Contributor

mdboom commented Oct 31, 2023

And the correct benchmarking results are in. With --disable-gil (and some hackery to get pyperf to build psutil from source), it's 1.06x slower at the 99th percentile on the HPT metric. Details here: https://github.com/faster-cpython/benchmarking-public/blob/main/results/bm-20231031-3.13.0a1%2B-bbb758f/bm-20231031-linux-x86_64-mdboom-measure_biased_ref_c-3.13.0a1%2B-bbb758f-vs-base.md

@mdboom
Copy link
Contributor

mdboom commented Oct 31, 2023

@colesbury: An interesting thing the benchmarking revealed is the coverage benchmark significantly regressed, but that may be due to failing to install a C extension and falling back to a pure Python codepath.

@colesbury
Copy link
Contributor Author

@mdboom, Yeah the coverage C extension fails to install due to pypa/packaging#727. That's fixed in the packaging main branch, but still needs a number of steps:

  1. A packaging release
  2. Vendor the new packaging release in pip
  3. A pip release
  4. New bundled copy of pip in cpython's ensurepip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants