8000 GH-130396: Work around for broken `pthread_get_stackaddr_np` on Emscr… · python/cpython@f3e275f · GitHub
[go: up one dir, main page]

Skip to content

Commit f3e275f

Browse files
authored
GH-130396: Work around for broken pthread_get_stackaddr_np on Emscripten (#131088)
Implements a workaround implementation of `pthread_get_stackaddr_np` for Emscripten. This will be replaced by an implementation that will be included in Emscripten 4.0.6.
1 parent 1121c80 commit f3e275f

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

Python/ceval.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,65 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate)
366366
# define Py_C_STACK_SIZE 4000000
367367
#endif
368368

369+
#if defined(__EMSCRIPTEN__)
370+
371+
// Temporary workaround to make `pthread_getattr_np` work on Emscripten.
372+
// Emscripten 4.0.6 will contain a fix:
373+
// https://github.com/emscripten-core/emscripten/pull/23887
374+
375+
#include "emscripten/stack.h"
376+
377+
#define pthread_attr_t workaround_pthread_attr_t
378+
#define pthread_getattr_np workaround_pthread_getattr_np
379+
#define pthread_attr_getguardsize workaround_pthread_attr_getguardsize
380+
#define pthread_attr_getstack workaround_pthread_attr_getstack
381+
#define pthread_attr_destroy workaround_pthread_attr_destroy
382+
383+
typedef struct {
384+
void *_a_stackaddr;
385+
size_t _a_stacksize, _a_guardsize;
386+
} pthread_attr_t;
387+
388+
extern __attribute__((__visibility__("hidden"))) unsigned __default_guardsize;
389+
390+
// Modified version of pthread_getattr_np from the upstream PR.
391+
392+
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) {
393+
attr->_a_stackaddr = (void*)emscripten_stack_get_base();
394+
attr->_a_stacksize = emscripten_stack_get_base() - emscripten_stack_get_end();
395+
attr->_a_guardsize = __default_guardsize;
396+
return 0;
397+
}
398+
399+
// These three functions copied without any changes from Emscripten libc.
400+
401+
int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
402+
{
403+
*size = a->_a_guardsize;
404+
return 0;
405+
}
406+
407+
int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
408+
{
409+
/// XXX musl is not standard-conforming? It should not report EINVAL if _a_stackaddr is zero, and it should
410+
/// report EINVAL if a is null: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstack.html
411+
if (!a) return EINVAL;
412+
// if (!a->_a_stackaddr)
413+
// return EINVAL;
414+
415+
*size = a->_a_stacksize;
416+
*addr = (void *)(a->_a_stackaddr - *size);
417+
return 0;
418+
}
419+
420+
int pthread_attr_destroy(pthread_attr_t *a)
421+
{
422+
return 0;
423+
}
424+
425+
#endif
426+
427+
369428
void
370429
_Py_InitializeRecursionLimits(PyThreadState *tstate)
371430
{

0 commit comments

Comments
 (0)
0