diff options
author | Oz Linden <oz@lindenlab.com> | 2012-11-19 11:09:58 -0500 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2012-11-19 11:09:58 -0500 |
commit | b7f8a2479249646c7fb38ead195d5197ab733c94 (patch) | |
tree | c1bf4a2b0ecac69a4705827a042ea7f0224ebc54 /indra/llcommon | |
parent | c94756d92c7353cb91bfddb5e342f825457e1a7e (diff) | |
parent | f8749ec9bd03072cc5b50f4cb1a61289b2989c72 (diff) |
merge up to 3.4.1-release
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llallocator.cpp | 2 | ||||
-rw-r--r-- | indra/llcommon/llapp.cpp | 3 | ||||
-rw-r--r-- | indra/llcommon/llmemory.cpp | 43 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 64 | ||||
-rw-r--r-- | indra/llcommon/llqueuedthread.cpp | 4 | ||||
-rw-r--r-- | indra/llcommon/llthread.cpp | 35 | ||||
-rw-r--r-- | indra/llcommon/llthread.h | 31 | ||||
-rw-r--r-- | indra/llcommon/llversionviewer.h | 2 |
8 files changed, 125 insertions, 59 deletions
diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 6f6abefc67..87654b5b97 100644 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "llallocator.h" -#if LL_USE_TCMALLOC +#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER) #include "google/heap-profiler.h" #include "google/commandlineflags_public.h" diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index ed192a9975..ca258900c7 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -289,6 +289,7 @@ void LLApp::setupErrorHandling() // occasionally checks to see if the app is in an error state, and sees if it needs to be run. #if LL_WINDOWS +#if LL_SEND_CRASH_REPORTS // This sets a callback to handle w32 signals to the console window. // The viewer shouldn't be affected, sicne its a windowed app. SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE); @@ -300,7 +301,7 @@ void LLApp::setupErrorHandling() mExceptionHandler = new google_breakpad::ExceptionHandler( L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL); } - +#endif #else // // Start up signal handling. diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 3b9758f996..70ad10ad55 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -61,6 +61,18 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; #endif +void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) +{ +#ifdef SHOW_ASSERT + // Redundant, place to set breakpoints. + if (ptr%alignment!=0) + { + llwarns << "alignment check failed" << llendl; + } + llassert(ptr%alignment==0); +#endif +} + //static void LLMemory::initClass() { @@ -240,21 +252,6 @@ U32 LLMemory::getAllocatedMemKB() return sAllocatedMemInKB ; } -void* ll_allocate (size_t size) -{ - if (size == 0) - { - llwarns << "Null allocation" << llendl; - } - void *p = malloc(size); - if (p == NULL) - { - LLMemory::freeReserve(); - llerrs << "Out of memory Error" << llendl; - } - return p; -} - //---------------------------------------------------------------------------- #if defined(LL_WINDOWS) @@ -1353,7 +1350,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) //if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it if(size >= CHUNK_SIZE) { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } char* p = NULL ; @@ -1410,7 +1407,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) to_log = false ; } - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } return p ; @@ -1429,7 +1426,7 @@ void LLPrivateMemoryPool::freeMem(void* addr) if(!chunk) { - free(addr) ; //release from heap + ll_aligned_free_16(addr) ; //release from heap } else { @@ -1553,7 +1550,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde mReservedPoolSize += preferred_size + overhead ; - char* buffer = (char*)malloc(preferred_size + overhead) ; + char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ; if(!buffer) { return NULL ; @@ -1621,7 +1618,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) mReservedPoolSize -= chunk->getBufferSize() ; //release memory - free(chunk->getBuffer()) ; + ll_aligned_free_16(chunk->getBuffer()) ; } U16 LLPrivateMemoryPool::findHashKey(const char* addr) @@ -1965,7 +1962,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, if(!poolp) { - p = (char*)malloc(size) ; + p = (char*)ll_aligned_malloc_16(size) ; } else { @@ -1994,7 +1991,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size) } else { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } } #endif @@ -2019,7 +2016,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr { if(!sPrivatePoolEnabled) { - free(addr) ; //private pool is disabled. + ll_aligned_free_16(addr) ; //private pool is disabled. } else if(!sInstance) //the private memory manager is destroyed, try the dangling list { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index bbbdaa6497..10013e0f92 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,13 @@ #define LLMEMORY_H #include "llmemtype.h" -#if LL_DEBUG + +#if LL_WINDOWS && LL_DEBUG +#define LL_CHECK_MEMORY llassert(_CrtCheckMemory()); +#else +#define LL_CHECK_MEMORY +#endif + inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -43,10 +49,11 @@ inline void ll_aligned_free( void* ptr ) free( ((void**)ptr)[-1] ); } +#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 16); + return _aligned_malloc(size, 16); #elif defined(LL_DARWIN) return malloc(size); // default osx malloc is 16 byte aligned. #else @@ -61,7 +68,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_16(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) return free(p); #else @@ -69,10 +76,39 @@ inline void ll_aligned_free_16(void *p) #endif } +inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16(). +{ +#if defined(LL_WINDOWS) + return _aligned_realloc(ptr, size, 16); +#elif defined(LL_DARWIN) + return realloc(ptr,size); // default osx malloc is 16 byte aligned. +#else + //FIXME: memcpy is SLOW + void* ret = ll_aligned_malloc_16(size); + if (ptr) + { + if (ret) + { + // Only copy the size of the smallest memory block to avoid memory corruption. + memcpy(ret, ptr, llmin(old_size, size)); + } + ll_aligned_free_16(ptr); + } + return ret; +#endif +} + +#else // USE_TCMALLOC +// ll_aligned_foo_16 are not needed with tcmalloc +#define ll_aligned_malloc_16 malloc +#define ll_aligned_realloc_16(a,b,c) realloc(a,b) +#define ll_aligned_free_16 free +#endif // USE_TCMALLOC + inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 32); + return _aligned_malloc(size, 32); #elif defined(LL_DARWIN) return ll_aligned_malloc( size, 32 ); #else @@ -87,22 +123,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_32(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) ll_aligned_free( p ); #else free(p); // posix_memalign() is compatible with heap deallocator #endif } -#else // LL_DEBUG -// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) -#define ll_aligned_malloc( size, align ) malloc(size) -#define ll_aligned_free( ptr ) free(ptr) -#define ll_aligned_malloc_16 malloc -#define ll_aligned_free_16 free -#define ll_aligned_malloc_32 malloc -#define ll_aligned_free_32 free -#endif // LL_DEBUG #ifndef __DEBUG_PRIVATE_MEM__ #define __DEBUG_PRIVATE_MEM__ 0 @@ -512,4 +539,13 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) // LLSingleton moved to llsingleton.h +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + +#ifdef SHOW_ASSERT +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment)) +#else +#define ll_assert_aligned(ptr,alignment) +#endif + + #endif diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 1738c16dea..abf47a0f57 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -134,8 +134,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms) pending = getPending(); if(pending > 0) { - unpause(); - } + unpause(); + } } else { diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index a6ad6b125c..c2fbb544a8 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -114,7 +114,7 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread } mRunCondition = new LLCondition(mAPRPoolp); - + mDataLock = new LLMutex(mAPRPoolp); mLocalAPRFilePoolp = NULL ; } @@ -173,7 +173,10 @@ void LLThread::shutdown() } delete mRunCondition; - mRunCondition = 0; + mRunCondition = NULL; + + delete mDataLock; + mDataLock = NULL; if (mIsLocalPool && mAPRPoolp) { @@ -242,28 +245,30 @@ bool LLThread::runCondition(void) // Stop thread execution if requested until unpaused. void LLThread::checkPause() { - mRunCondition->lock(); + mDataLock->lock(); // This is in a while loop because the pthread API allows for spurious wakeups. while(shouldSleep()) { + mDataLock->unlock(); mRunCondition->wait(); // unlocks mRunCondition + mDataLock->lock(); // mRunCondition is locked when the thread wakes up } - mRunCondition->unlock(); + mDataLock->unlock(); } //============================================================================ void LLThread::setQuitting() { - mRunCondition->lock(); + mDataLock->lock(); if (mStatus == RUNNING) { mStatus = QUITTING; } - mRunCondition->unlock(); + mDataLock->unlock(); wake(); } @@ -285,12 +290,12 @@ void LLThread::yield() void LLThread::wake() { - mRunCondition->lock(); + mDataLock->lock(); if(!shouldSleep()) { mRunCondition->signal(); } - mRunCondition->unlock(); + mDataLock->unlock(); } void LLThread::wakeLocked() @@ -481,6 +486,19 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() : { } +LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src) +{ + if (sMutex) + { + sMutex->lock(); + } + mRef = 0; + if (sMutex) + { + sMutex->unlock(); + } +} + LLThreadSafeRefCount::~LLThreadSafeRefCount() { if (mRef != 0) @@ -489,6 +507,7 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount() } } + //============================================================================ LLResponder::~LLResponder() diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b52e70ab2e..115bf47553 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -97,6 +97,7 @@ private: protected: std::string mName; LLCondition* mRunCondition; + LLMutex* mDataLock; apr_thread_t *mAPRThreadp; apr_pool_t *mAPRPoolp; @@ -122,15 +123,15 @@ protected: inline void unlockData(); // This is the predicate that decides whether the thread should sleep. - // It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access + // It should only be called with mDataLock locked, since the virtual runCondition() function may need to access // data structures that are thread-unsafe. bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); } // To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following: - // mRunCondition->lock(); + // mDataLock->lock(); // if(!shouldSleep()) // mRunCondition->signal(); - // mRunCondition->unlock(); + // mDataLock->unlock(); }; //============================================================================ @@ -205,12 +206,12 @@ private: void LLThread::lockData() { - mRunCondition->lock(); + mDataLock->lock(); } void LLThread::unlockData() { - mRunCondition->unlock(); + mDataLock->unlock(); } @@ -227,15 +228,27 @@ public: private: static LLMutex* sMutex; -private: - LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented - LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented - protected: virtual ~LLThreadSafeRefCount(); // use unref() public: LLThreadSafeRefCount(); + LLThreadSafeRefCount(const LLThreadSafeRefCount&); + LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) + { + if (sMutex) + { + sMutex->lock(); + } + mRef = 0; + if (sMutex) + { + sMutex->unlock(); + } + return *this; + } + + void ref() { diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 2038681905..bcc661a920 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@ const S32 LL_VERSION_MAJOR = 3; const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 0; +const S32 LL_VERSION_PATCH = 1; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; |