FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[3.15] gh-159603: Use pthread_attr_get_np() on FreeBSD (#159604) (#15… · python/cpython@b62f612 · GitHub

Repository navigation

Commit b62f612

Browse files
authored
[3.15] gh-159603: Use pthread_attr_get_np() on FreeBSD (#159604) (#159928)
gh-159603: Use pthread_attr_get_np() on FreeBSD (#159604) Use pthread_attr_get_np() on FreeBSD to get the stack size (and guard size) of the current thread. Check if pthread_attr_get_np() function and <pthread_np.h> header are available in configure. Update test_json.test_recursion. On FreeBSD 16 with a default stack size of 512 MB, the json C implementation no longer raises RecursionError in test_highly_nested_objects_encoding(). Reduce also max_depth from 5,000 to 2,000 so test_highly_nested_objects_encoding() of the Python implementation only takes 1.6 seconds, instead of 12 seconds. (cherry picked from commit 71ba39d)
1 parent 0405f10 commit b62f612

6 files changed

Lines changed: 94 additions & 11 deletions

File tree

‎Lib/test/test_json/test_recursion.py‎

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,35 @@ def test_highly_nested_objects_decoding(self):
9191
@support.skip_emscripten_stack_overflow()
9292
@support.requires_resource('cpu')
9393
def test_highly_nested_objects_encoding(self):
94-
# See #12051
94+
# See issue gh-56260
95+
96+
# With max_depth=2_000 on Linux, the Python implementation takes around
97+
# 2 seconds to raise RecursionError, whereas the C implementation only
98+
# takes around 160 ms.
99+
max_depth = 2_000
95100
l, d = [], {}
96-
for x in range(500_000):
101+
for x in range(max_depth * 10):
97102
l, d = [l], {'k':d}
98-
with self.assertRaises(RecursionError):
99-
with support.infinite_recursion(5000):
103+
104+
# Don't use assertRaises(RecursionError): on FreeBSD 16 with a default
105+
# stack size of 512 MiB, the C implementation doesn't raise
106+
# RecursionError.
107+
try:
108+
with support.infinite_recursion(max_depth):
100109
self.dumps(l)
101-
with self.assertRaises(RecursionError):
102-
with support.infinite_recursion(5000):
110+
except RecursionError:
111+
pass
112+
try:
113+
with support.infinite_recursion(max_depth):
103114
self.dumps(d)
115+
except RecursionError:
116+
pass
104117

105118
@support.skip_if_huge_c_stack()
106119
@support.skip_emscripten_stack_overflow()
107120
@support.skip_wasi_stack_overflow()
108121
def test_endless_recursion(self):
109-
# See #12051
122+
# See issue gh-56260
110123
class EndlessJSONEncoder(self.json.JSONEncoder):
111124
def default(self, o):
112125
"""If check_circular is False, this will keep adding another list."""
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
On FreeBSD, call ``pthread_attr_get_np()`` to get the stack size (and guard
2+
size) of the current thread. Patch by Victor Stinner.

‎Python/ceval.c‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include "ceval.h"
44
#include "pycore_long.h"
55

6+
#ifdef HAVE_PTHREAD_NP_H
7+
# include <pthread_np.h> // pthread_attr_get_np()
8+
#endif
9+
10+
611
int
712
Py_GetRecursionLimit(void)
813
{
@@ -159,13 +164,18 @@ hardware_stack_limits(uintptr_t *base, uintptr_t *top, uintptr_t sp)
159164
// limits compared to the old stack size estimation. musl doesn't give
160165
// us a way to detect it, so we have to assume any non-glibc,
161166
// non-Android Linux is musl and mustn't rely on pthread_getattr_np.
162-
# if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && \
163-
!defined(__NetBSD__) && \
164-
(defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__))
167+
# if (defined(HAVE_PTHREAD_GETATTR_NP) || defined(_Py_HAVE_PTHREAD_ATTR_GET_NP)) \
168+
&& !defined(_AIX) && !defined(__NetBSD__) \
169+
&& (defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__))
165170
size_t stack_size, guard_size;
166171
void *stack_addr;
167172
pthread_attr_t attr;
173+
#ifdef _Py_HAVE_PTHREAD_ATTR_GET_NP
174+
int err = pthread_attr_init(&attr);
175+
err |= pthread_attr_get_np(pthread_self(), &attr);
176+
#else
168177
int err = pthread_getattr_np(pthread_self(), &attr);
178+
#endif
169179
if (err == 0) {
170180
err = pthread_attr_getguardsize(&attr, &guard_size);
171181
err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size);

‎configure‎

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎configure.ac‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3168,7 +3168,8 @@ AC_CHECK_HEADERS([ \
31683168
alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
31693169
io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \
31703170
linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h \
3171-
linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \
3171+
linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h \
3172+
poll.h process.h pthread.h pthread_np.h pty.h \
31723173
sched.h setjmp.h shadow.h signal.h spawn.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \
31733174
sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \
31743175
sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/pidfd.h sys/poll.h \
@@ -5523,6 +5524,8 @@ AC_CHECK_FUNCS([ \
55235524
])
55245525

55255526
PY_CHECK_FUNC_PRIVATE([strerror_r], [@%:@include <string.h>])
5527+
# FreeBSD pthread_attr_get_np()
5528+
PY_CHECK_FUNC_PRIVATE([pthread_attr_get_np], [@%:@include <pthread_np.h>])
55265529

55275530

55285531
# os.statx uses Linux's statx function. AIX also has a function named statx,

‎pyconfig.h.in‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,9 @@
10481048
/* Define to 1 if you have the 'pthread_kill' function. */
10491049
#undef HAVE_PTHREAD_KILL
10501050

1051+
/* Define to 1 if you have the <pthread_np.h> header file. */
1052+
#undef HAVE_PTHREAD_NP_H
1053+
10511054
/* Define to 1 if you have the 'pthread_setname_np' function. */
10521055
#undef HAVE_PTHREAD_SETNAME_NP
10531056

@@ -2094,6 +2097,9 @@
20942097
/* Define if you have the 'PR_SET_VMA_ANON_NAME' constant. */
20952098
#undef _Py_HAVE_PR_SET_VMA_ANON_NAME
20962099

2100+
/* Define if you have the 'pthread_attr_get_np' function. */
2101+
#undef _Py_HAVE_PTHREAD_ATTR_GET_NP
2102+
20972103
/* Define if you have the 'strerror_r' function. */
20982104
#undef _Py_HAVE_STRERROR_R
20992105

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL