mirror of
https://github.com/python/cpython.git
synced 2025-07-27 05:04:15 +00:00

46640 Patch #1454481: Make thread stack size runtime tunable. 46647 Markup fix The first is causing many buildbots to fail test runs, and there are multiple causes with seemingly no immediate prospects for repairing them. See python-dev discussion. Note that a branch can (and should) be created for resolving these problems, like svn copy svn+ssh://svn.python.org/python/trunk -r46640 svn+ssh://svn.python.org/python/branches/NEW_BRANCH followed by merging rev 46647 to the new branch.
277 lines
5 KiB
C
277 lines
5 KiB
C
/* This code implemented by cvale@netcom.com */
|
|
|
|
#define INCL_DOSPROCESS
|
|
#define INCL_DOSSEMAPHORES
|
|
#include "os2.h"
|
|
#include "limits.h"
|
|
|
|
#include "process.h"
|
|
|
|
#if defined(PYCC_GCC)
|
|
#include <sys/builtin.h>
|
|
#include <sys/fmutex.h>
|
|
#else
|
|
long PyThread_get_thread_ident(void);
|
|
#endif
|
|
|
|
#if !defined(THREAD_STACK_SIZE)
|
|
#define THREAD_STACK_SIZE 0x10000
|
|
#endif
|
|
|
|
/*
|
|
* Initialization of the C package, should not be needed.
|
|
*/
|
|
static void
|
|
PyThread__init_thread(void)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Thread support.
|
|
*/
|
|
long
|
|
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|
{
|
|
int aThread;
|
|
int success = 0;
|
|
|
|
aThread = _beginthread(func, NULL, THREAD_STACK_SIZE, arg);
|
|
|
|
if (aThread == -1) {
|
|
success = -1;
|
|
fprintf(stderr, "aThread failed == %d", aThread);
|
|
dprintf(("_beginthread failed. return %ld\n", errno));
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
long
|
|
PyThread_get_thread_ident(void)
|
|
{
|
|
#if !defined(PYCC_GCC)
|
|
PPIB pib;
|
|
PTIB tib;
|
|
#endif
|
|
|
|
if (!initialized)
|
|
PyThread_init_thread();
|
|
|
|
#if defined(PYCC_GCC)
|
|
return _gettid();
|
|
#else
|
|
DosGetInfoBlocks(&tib, &pib);
|
|
return tib->tib_ptib2->tib2_ultid;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
do_PyThread_exit_thread(int no_cleanup)
|
|
{
|
|
dprintf(("%ld: PyThread_exit_thread called\n",
|
|
PyThread_get_thread_ident()));
|
|
if (!initialized)
|
|
if (no_cleanup)
|
|
_exit(0);
|
|
else
|
|
exit(0);
|
|
_endthread();
|
|
}
|
|
|
|
void
|
|
PyThread_exit_thread(void)
|
|
{
|
|
do_PyThread_exit_thread(0);
|
|
}
|
|
|
|
void
|
|
PyThread__exit_thread(void)
|
|
{
|
|
do_PyThread_exit_thread(1);
|
|
}
|
|
|
|
#ifndef NO_EXIT_PROG
|
|
static void
|
|
do_PyThread_exit_prog(int status, int no_cleanup)
|
|
{
|
|
dprintf(("PyThread_exit_prog(%d) called\n", status));
|
|
if (!initialized)
|
|
if (no_cleanup)
|
|
_exit(status);
|
|
else
|
|
exit(status);
|
|
}
|
|
|
|
void
|
|
PyThread_exit_prog(int status)
|
|
{
|
|
do_PyThread_exit_prog(status, 0);
|
|
}
|
|
|
|
void
|
|
PyThread__exit_prog(int status)
|
|
{
|
|
do_PyThread_exit_prog(status, 1);
|
|
}
|
|
#endif /* NO_EXIT_PROG */
|
|
|
|
/*
|
|
* Lock support. This is implemented with an event semaphore and critical
|
|
* sections to make it behave more like a posix mutex than its OS/2
|
|
* counterparts.
|
|
*/
|
|
|
|
typedef struct os2_lock_t {
|
|
int is_set;
|
|
HEV changed;
|
|
} *type_os2_lock;
|
|
|
|
PyThread_type_lock
|
|
PyThread_allocate_lock(void)
|
|
{
|
|
#if defined(PYCC_GCC)
|
|
_fmutex *sem = malloc(sizeof(_fmutex));
|
|
if (!initialized)
|
|
PyThread_init_thread();
|
|
dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
|
|
PyThread_get_thread_ident(),
|
|
(long)sem));
|
|
if (_fmutex_create(sem, 0)) {
|
|
free(sem);
|
|
sem = NULL;
|
|
}
|
|
return (PyThread_type_lock)sem;
|
|
#else
|
|
APIRET rc;
|
|
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
|
|
|
|
dprintf(("PyThread_allocate_lock called\n"));
|
|
if (!initialized)
|
|
PyThread_init_thread();
|
|
|
|
lock->is_set = 0;
|
|
|
|
DosCreateEventSem(NULL, &lock->changed, 0, 0);
|
|
|
|
dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
|
|
PyThread_get_thread_ident(),
|
|
lock->changed));
|
|
|
|
return (PyThread_type_lock)lock;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
PyThread_free_lock(PyThread_type_lock aLock)
|
|
{
|
|
#if !defined(PYCC_GCC)
|
|
type_os2_lock lock = (type_os2_lock)aLock;
|
|
#endif
|
|
|
|
dprintf(("%ld: PyThread_free_lock(%p) called\n",
|
|
PyThread_get_thread_ident(),aLock));
|
|
|
|
#if defined(PYCC_GCC)
|
|
if (aLock) {
|
|
_fmutex_close((_fmutex *)aLock);
|
|
free((_fmutex *)aLock);
|
|
}
|
|
#else
|
|
DosCloseEventSem(lock->changed);
|
|
free(aLock);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Return 1 on success if the lock was acquired
|
|
*
|
|
* and 0 if the lock was not acquired.
|
|
*/
|
|
int
|
|
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
|
|
{
|
|
#if !defined(PYCC_GCC)
|
|
int done = 0;
|
|
ULONG count;
|
|
PID pid = 0;
|
|
TID tid = 0;
|
|
type_os2_lock lock = (type_os2_lock)aLock;
|
|
#endif
|
|
|
|
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
|
|
PyThread_get_thread_ident(),
|
|
aLock,
|
|
waitflag));
|
|
|
|
#if defined(PYCC_GCC)
|
|
/* always successful if the lock doesn't exist */
|
|
if (aLock &&
|
|
_fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
|
|
return 0;
|
|
#else
|
|
while (!done) {
|
|
/* if the lock is currently set, we have to wait for
|
|
* the state to change
|
|
*/
|
|
if (lock->is_set) {
|
|
if (!waitflag)
|
|
return 0;
|
|
DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
|
|
}
|
|
|
|
/* enter a critical section and try to get the semaphore. If
|
|
* it is still locked, we will try again.
|
|
*/
|
|
if (DosEnterCritSec())
|
|
return 0;
|
|
|
|
if (!lock->is_set) {
|
|
lock->is_set = 1;
|
|
DosResetEventSem(lock->changed, &count);
|
|
done = 1;
|
|
}
|
|
|
|
DosExitCritSec();
|
|
}
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
PyThread_release_lock(PyThread_type_lock aLock)
|
|
{
|
|
#if !defined(PYCC_GCC)
|
|
type_os2_lock lock = (type_os2_lock)aLock;
|
|
#endif
|
|
|
|
dprintf(("%ld: PyThread_release_lock(%p) called\n",
|
|
PyThread_get_thread_ident(),
|
|
aLock));
|
|
|
|
#if defined(PYCC_GCC)
|
|
if (aLock)
|
|
_fmutex_release((_fmutex *)aLock);
|
|
#else
|
|
if (!lock->is_set) {
|
|
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
|
PyThread_get_thread_ident(),
|
|
aLock,
|
|
GetLastError()));
|
|
return;
|
|
}
|
|
|
|
if (DosEnterCritSec()) {
|
|
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
|
PyThread_get_thread_ident(),
|
|
aLock,
|
|
GetLastError()));
|
|
return;
|
|
}
|
|
|
|
lock->is_set = 0;
|
|
DosPostEventSem(lock->changed);
|
|
|
|
DosExitCritSec();
|
|
#endif
|
|
}
|