mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									1121c80fda
								
							
						
					
					
						commit
						f3e275f1a9
					
				
					 1 changed files with 59 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -366,6 +366,65 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate)
 | 
			
		|||
#  define Py_C_STACK_SIZE 4000000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__EMSCRIPTEN__)
 | 
			
		||||
 | 
			
		||||
// Temporary workaround to make `pthread_getattr_np` work on Emscripten.
 | 
			
		||||
// Emscripten 4.0.6 will contain a fix:
 | 
			
		||||
// https://github.com/emscripten-core/emscripten/pull/23887
 | 
			
		||||
 | 
			
		||||
#include "emscripten/stack.h"
 | 
			
		||||
 | 
			
		||||
#define pthread_attr_t workaround_pthread_attr_t
 | 
			
		||||
#define pthread_getattr_np workaround_pthread_getattr_np
 | 
			
		||||
#define pthread_attr_getguardsize workaround_pthread_attr_getguardsize
 | 
			
		||||
#define pthread_attr_getstack workaround_pthread_attr_getstack
 | 
			
		||||
#define pthread_attr_destroy workaround_pthread_attr_destroy
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    void *_a_stackaddr;
 | 
			
		||||
    size_t _a_stacksize, _a_guardsize;
 | 
			
		||||
} pthread_attr_t;
 | 
			
		||||
 | 
			
		||||
extern __attribute__((__visibility__("hidden"))) unsigned __default_guardsize;
 | 
			
		||||
 | 
			
		||||
// Modified version of pthread_getattr_np from the upstream PR.
 | 
			
		||||
 | 
			
		||||
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) {
 | 
			
		||||
  attr->_a_stackaddr = (void*)emscripten_stack_get_base();
 | 
			
		||||
  attr->_a_stacksize = emscripten_stack_get_base() - emscripten_stack_get_end();
 | 
			
		||||
  attr->_a_guardsize = __default_guardsize;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// These three functions copied without any changes from Emscripten libc.
 | 
			
		||||
 | 
			
		||||
int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
 | 
			
		||||
{
 | 
			
		||||
	*size = a->_a_guardsize;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
 | 
			
		||||
{
 | 
			
		||||
/// XXX musl is not standard-conforming? It should not report EINVAL if _a_stackaddr is zero, and it should
 | 
			
		||||
///     report EINVAL if a is null: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstack.html
 | 
			
		||||
	if (!a) return EINVAL;
 | 
			
		||||
//	if (!a->_a_stackaddr)
 | 
			
		||||
//		return EINVAL;
 | 
			
		||||
 | 
			
		||||
	*size = a->_a_stacksize;
 | 
			
		||||
	*addr = (void *)(a->_a_stackaddr - *size);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pthread_attr_destroy(pthread_attr_t *a)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_Py_InitializeRecursionLimits(PyThreadState *tstate)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue