From f45ae6a4d858e2cf0cf1f26c50eb62138287dc19 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Nov 2009 10:27:43 +0000 Subject: [PATCH] From David Fries, "I was trying to create a lot of threads under 32 bit Linux, but could only create 376, then the program would hang. 376 * 8MB stack per thread = 3008 MB The stack size allocated per thread blew the process address stack. To get more threads you have to specify a smaller per thread stack, but while the Thread::start says it will limit the stack size to the smallest allowable stack size, it won't let it be smaller than the default. I included the limits.h header to use PTHREAD_STACK_MIN as the minimum stack size. As for the deadlock, if the pthread_create failed, the new thread doesn't exist and doesn't call threadStartedBlock.release(), so the existing thread deadlocks on threadStartedBlock.block(). Only block if the thread was started." --- include/osgDB/Output | 2 ++ src/OpenThreads/pthreads/PThread.c++ | 45 +++++++++++++--------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/include/osgDB/Output b/include/osgDB/Output index 1efedcdb7..24264c96e 100644 --- a/include/osgDB/Output +++ b/include/osgDB/Output @@ -91,9 +91,11 @@ class OSGDB_EXPORT Output : public osgDB::ofstream virtual std::string getFileNameForOutput(const std::string& filename) const; const std::string& getFileName() const { return _filename; } + // Set and get if export texture files during write void setOutputTextureFiles(bool flag) { _outputTextureFiles = flag; } bool getOutputTextureFiles() const { return _outputTextureFiles; } + // support code for OutputTextureFiles virtual std::string getTextureFileNameForOutput(); void setOutputShaderFiles(bool flag) { _outputShaderFiles = flag; } diff --git a/src/OpenThreads/pthreads/PThread.c++ b/src/OpenThreads/pthreads/PThread.c++ index db0b864b5..0f46a138d 100644 --- a/src/OpenThreads/pthreads/PThread.c++ +++ b/src/OpenThreads/pthreads/PThread.c++ @@ -21,6 +21,7 @@ #include #include #include +#include #if defined __linux || defined __sun || defined __APPLE__ #include @@ -588,29 +589,28 @@ int Thread::start() { PThreadPrivateData *pd = static_cast (_prvData); - size_t defaultStackSize; - pthread_attr_getstacksize( &thread_attr, &defaultStackSize); - if(status != 0) { - return status; - } - - if(defaultStackSize < pd->stackSize) { - - pthread_attr_setstacksize( &thread_attr, pd->stackSize); - if(status != 0) { - return status; - } + //------------------------------------------------------------------------- + // Set the stack size if requested, but not less than a platform reasonable + // value. + // + if(pd->stackSize) { + if(pd->stackSize < PTHREAD_STACK_MIN) + pd->stackSize = PTHREAD_STACK_MIN; + pthread_attr_setstacksize( &thread_attr, pd->stackSize); + if(status != 0) { + return status; + } } //------------------------------------------------------------------------- // Now get what we actually have... // - pthread_attr_getstacksize( &thread_attr, &defaultStackSize); + size_t size; + pthread_attr_getstacksize( &thread_attr, &size); if(status != 0) { return status; } - - pd->stackSize = defaultStackSize; + pd->stackSize = size; //------------------------------------------------------------------------- // Prohibit the stack size from being changed. @@ -635,18 +635,15 @@ int Thread::start() { status = pthread_create(&(pd->tid), &thread_attr, ThreadPrivateActions::StartThread, static_cast(this)); - - // wait till the thread has actually started. - pd->threadStartedBlock.block(); - if(status != 0) { - return status; + if(status == 0) { + // wait till the thread has actually started. + pd->threadStartedBlock.block(); + + pd->idSet = true; } - pd->idSet = true; - - return 0; - + return status; } //-----------------------------------------------------------------------------