diff options
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/thread.c | 33 | ||||
| -rw-r--r-- | Python/thread_nt.h | 36 | ||||
| -rw-r--r-- | Python/thread_os2.h | 42 | ||||
| -rw-r--r-- | Python/thread_pthread.h | 63 | 
4 files changed, 170 insertions, 4 deletions
diff --git a/Python/thread.c b/Python/thread.c index 5e7fc6ccc1..dd9c3ad588 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -94,6 +94,31 @@ void PyThread_init_thread(void)  	PyThread__init_thread();  } +/* Support for runtime thread stack size tuning. +   A value of 0 means using the platform's default stack size +   or the size specified by the THREAD_STACK_SIZE macro. */ +static size_t _pythread_stacksize = 0; + +size_t +PyThread_get_stacksize(void) +{ +	return _pythread_stacksize; +} + +static int +_pythread_unsupported_set_stacksize(size_t size) +{ +	return PyErr_Warn(PyExc_RuntimeWarning, +			  "setting thread stack size not supported on " +                          "this platform"); +} + +/* Only platforms with THREAD_SET_STACKSIZE() defined in +   pthread_<platform>.h, overriding this default definition, +   will support changing the stack size. +   Return 1 if an exception is pending, 0 otherwise. */ +#define THREAD_SET_STACKSIZE(x)	_pythread_unsupported_set_stacksize(x) +  #ifdef SGI_THREADS  #include "thread_sgi.h"  #endif @@ -149,6 +174,14 @@ void PyThread_init_thread(void)  #endif  */ +/* use appropriate thread stack size setting routine. +   Return 1 if an exception is pending, 0 otherwise. */ +int +PyThread_set_stacksize(size_t size) +{ +	return THREAD_SET_STACKSIZE(size); +} +  #ifndef Py_HAVE_NATIVE_TLS  /* If the platform has not supplied a platform specific     TLS implementation, provide our own. diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 5141053b03..8f5f996b46 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -185,7 +185,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)  	if (obj.done == NULL)  		return -1; -	rv = _beginthread(bootstrap, 0, &obj); /* use default stack size */ +	rv = _beginthread(bootstrap, _pythread_stacksize, &obj);  	if (rv == (Py_uintptr_t)-1) {  		/* I've seen errno == EAGAIN here, which means "there are  		 * too many threads". @@ -313,3 +313,37 @@ void PyThread_release_lock(PyThread_type_lock aLock)  	if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))  		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));  } + +/* minimum/maximum thread stack sizes supported */ +#define THREAD_MIN_STACKSIZE	0x8000		/* 32kB */ +#define THREAD_MAX_STACKSIZE	0x10000000	/* 256MB */ + +/* set the thread stack size. + * Return 1 if an exception is pending, 0 otherwise. + */ +static int +_pythread_nt_set_stacksize(size_t size) +{ +	/* set to default */ +	if (size == 0) { +		_pythread_stacksize = 0; +		return 0; +	} + +	/* valid range? */ +	if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) { +		_pythread_stacksize = size; +		return 0; +	} +	else { +		char warning[128]; +		snprintf(warning, +			 128, +			 "thread stack size of %#x bytes not supported on Win32", +			 size); +		return PyErr_Warn(PyExc_RuntimeWarning, warning); +	} +} + +#undef THREAD_SET_STACKSIZE +#define THREAD_SET_STACKSIZE(x)	_pythread_nt_set_stacksize(x) diff --git a/Python/thread_os2.h b/Python/thread_os2.h index a18ce6fd6c..91959a0951 100644 --- a/Python/thread_os2.h +++ b/Python/thread_os2.h @@ -14,10 +14,13 @@  long PyThread_get_thread_ident(void);  #endif +/* default thread stack size of 64kB */  #if !defined(THREAD_STACK_SIZE)  #define	THREAD_STACK_SIZE	0x10000  #endif +#define OS2_STACKSIZE(x)	(x ? x : THREAD_STACK_SIZE) +  /*   * Initialization of the C package, should not be needed.   */ @@ -35,7 +38,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)  	int aThread;  	int success = 0; -	aThread = _beginthread(func, NULL, THREAD_STACK_SIZE, arg); +	aThread = _beginthread(func, +				NULL, +				OS2_STACKSIZE(_pythread_stacksize), +				arg);  	if (aThread == -1) {  		success = -1; @@ -274,3 +280,37 @@ void PyThread_release_lock(PyThread_type_lock aLock)  	DosExitCritSec();  #endif  } + +/* minimum/maximum thread stack sizes supported */ +#define THREAD_MIN_STACKSIZE	0x8000		/* 32kB */ +#define THREAD_MAX_STACKSIZE	0x2000000	/* 32MB */ + +/* set the thread stack size. + * Return 1 if an exception is pending, 0 otherwise. + */ +static int +_pythread_os2_set_stacksize(size_t size) +{ +	/* set to default */ +	if (size == 0) { +		_pythread_stacksize = 0; +		return 0; +	} + +	/* valid range? */ +	if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) { +		_pythread_stacksize = size; +		return 0; +	} +	else { +		char warning[128]; +		snprintf(warning, +			 128, +			 "thread stack size of %#x bytes not supported on OS/2", +			 size); +		return PyErr_Warn(PyExc_RuntimeWarning, warning); +	} +} + +#undef THREAD_SET_STACKSIZE +#define THREAD_SET_STACKSIZE(x)	_pythread_os2_set_stacksize(x) diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index c29a61c809..e2907e08b2 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -12,6 +12,24 @@  #endif  #include <signal.h> +/* The POSIX spec requires that use of pthread_attr_setstacksize +   be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ +#ifdef _POSIX_THREAD_ATTR_STACKSIZE +#ifndef THREAD_STACK_SIZE +#define	THREAD_STACK_SIZE	0	/* use default stack size */ +#endif +/* for safety, ensure a viable minimum stacksize */ +#define	THREAD_STACK_MIN	0x8000	/* 32kB */ +#if THREAD_STACK_MIN < PTHREAD_STACK_MIN +#undef THREAD_STACK_MIN +#define	THREAD_STACK_MIN	PTHREAD_STACK_MIN +#endif +#else  /* !_POSIX_THREAD_ATTR_STACKSIZE */ +#ifdef THREAD_STACK_SIZE +#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined" +#endif +#endif +  /* The POSIX spec says that implementations supporting the sem_*     family of functions must indicate this by defining     _POSIX_SEMAPHORES. */    @@ -138,6 +156,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)  #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)  	pthread_attr_t attrs;  #endif +#if defined(THREAD_STACK_SIZE) +	size_t	tss; +#endif +  	dprintf(("PyThread_start_new_thread called\n"));  	if (!initialized)  		PyThread_init_thread(); @@ -145,8 +167,15 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)  #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)  	pthread_attr_init(&attrs);  #endif -#ifdef THREAD_STACK_SIZE -	pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE); +#if defined(THREAD_STACK_SIZE) +	tss = (_pythread_stacksize != 0) ? _pythread_stacksize +					 : THREAD_STACK_SIZE; +	if (tss != 0) { +		if (pthread_attr_setstacksize(&attrs, tss) != 0) { +			pthread_attr_destroy(&attrs); +			return -1; +		} +	}  #endif  #if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)          pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); @@ -460,3 +489,33 @@ PyThread_release_lock(PyThread_type_lock lock)  }  #endif /* USE_SEMAPHORES */ + +/* set the thread stack size. + * Return 1 if an exception is pending, 0 otherwise. + */ +static int +_pythread_pthread_set_stacksize(size_t size) +{ +	/* set to default */ +	if (size == 0) { +		_pythread_stacksize = 0; +		return 0; +	} + +	/* valid range? */ +	if (size >= THREAD_STACK_MIN) { +		_pythread_stacksize = size; +		return 0; +	} +	else { +		char warning[128]; +		snprintf(warning, +			 128, +			 "thread stack size of %#x bytes not supported", +			 size); +		return PyErr_Warn(PyExc_RuntimeWarning, warning); +	} +} + +#undef THREAD_SET_STACKSIZE +#define THREAD_SET_STACKSIZE(x)	_pythread_pthread_set_stacksize(x)  | 
