summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llassettype.cpp3
-rw-r--r--indra/llcommon/llassettype.h6
-rw-r--r--indra/llcommon/lldefs.h8
-rw-r--r--indra/llcommon/llfoldertype.cpp3
-rw-r--r--indra/llcommon/llfoldertype.h6
-rw-r--r--indra/llcommon/llmemory.cpp19
-rw-r--r--indra/llcommon/llmemory.h71
-rw-r--r--indra/llcommon/llsdserialize.cpp139
-rw-r--r--indra/llcommon/llsdserialize.h4
-rw-r--r--indra/llcommon/llthread.cpp46
-rw-r--r--indra/llcommon/llthread.h22
-rw-r--r--indra/llcommon/stdenums.h3
12 files changed, 298 insertions, 32 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 2cd29448ae..bdd115364e 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -99,8 +99,9 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
+ addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
+ addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
- addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false));
};
// static
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 2c2dc27aaa..27d35e95ff 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -114,8 +114,10 @@ public:
AT_LINK_FOLDER = 25,
// Inventory folder link
-
- AT_COUNT = 26,
+ AT_MESH = 49,
+ // Mesh data in our proprietary SLM format
+
+ AT_COUNT = 50,
// +*********************************************************+
// | TO ADD AN ELEMENT TO THIS ENUM: |
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index f3b5ca361f..10e6cb34bf 100644
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
@@ -242,5 +242,13 @@ inline LLDATATYPE llclampb(const LLDATATYPE& a)
return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255);
}
+template <class LLDATATYPE>
+inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
+{
+ LLDATATYPE tmp = lhs;
+ lhs = rhs;
+ rhs = tmp;
+}
+
#endif // LL_LLDEFS_H
diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp
index 2610fe9e6a..16ae4cddde 100644
--- a/indra/llcommon/llfoldertype.cpp
+++ b/indra/llcommon/llfoldertype.cpp
@@ -95,6 +95,9 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", TRUE));
addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", FALSE));
addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", TRUE));
+
+ addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE));
+
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h
index 7aa77f7f7e..409112a04e 100644
--- a/indra/llcommon/llfoldertype.h
+++ b/indra/llcommon/llfoldertype.h
@@ -86,9 +86,11 @@ public:
FT_OUTFIT = 47,
FT_MY_OUTFITS = 48,
- FT_INBOX = 49,
+ FT_MESH = 49,
- FT_COUNT = 50,
+ FT_INBOX = 50,
+
+ FT_COUNT = 51,
FT_NONE = -1
};
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 2a8015e26d..5c6ca30cdd 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -73,25 +73,6 @@ void LLMemory::freeReserve()
reserveMem = NULL;
}
-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;
-}
-
-void ll_release (void *p)
-{
- free(p);
-}
//----------------------------------------------------------------------------
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 1c6f64dd8b..35935efa88 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -32,14 +32,75 @@
#ifndef LLMEMORY_H
#define LLMEMORY_H
+#include <stdlib.h>
+// A not necessarily efficient, but general, aligned malloc http://stackoverflow.com/questions/196329/osx-lacks-memalign
+inline void* ll_aligned_malloc( size_t size, int align )
+{
+ void* mem = malloc( size + (align - 1) + sizeof(void*) );
+ char* aligned = ((char*)mem) + sizeof(void*);
+ aligned += align - ((uintptr_t)aligned & (align - 1));
+
+ ((void**)aligned)[-1] = mem;
+ return aligned;
+}
-extern S32 gTotalDAlloc;
-extern S32 gTotalDAUse;
-extern S32 gDACount;
+inline void ll_aligned_free( void* ptr )
+{
+ free( ((void**)ptr)[-1] );
+}
-extern void* ll_allocate (size_t size);
-extern void ll_release (void *p);
+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);
+#elif defined(LL_DARWIN)
+ return malloc(size); // default osx malloc is 16 byte aligned.
+#else
+ void *rtn;
+ if (LL_LIKELY(0 == posix_memalign(&rtn, 16, size)))
+ return rtn;
+ else // bad alignment requested, or out of memory
+ return NULL;
+#endif
+}
+
+inline void ll_aligned_free_16(void *p)
+{
+#if defined(LL_WINDOWS)
+ _mm_free(p);
+#elif defined(LL_DARWIN)
+ return free(p);
+#else
+ free(p); // posix_memalign() is compatible with heap deallocator
+#endif
+}
+
+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);
+#elif defined(LL_DARWIN)
+ return ll_aligned_malloc( size, 32 );
+#else
+ void *rtn;
+ if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size)))
+ return rtn;
+ else // bad alignment requested, or out of memory
+ return NULL;
+#endif
+}
+
+inline void ll_aligned_free_32(void *p)
+{
+#if defined(LL_WINDOWS)
+ _mm_free(p);
+#elif defined(LL_DARWIN)
+ ll_aligned_free( p );
+#else
+ free(p); // posix_memalign() is compatible with heap deallocator
+#endif
+}
class LL_COMMON_API LLMemory
{
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index cf337be161..fdeb93e27f 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -39,6 +39,7 @@
#include <iostream>
#include "apr_base64.h"
+#include "zlib/zlib.h" // for davep's dirty little zip functions
#if !LL_WINDOWS
#include <netinet/in.h> // htonl & ntohl
@@ -1989,3 +1990,141 @@ std::ostream& operator<<(std::ostream& s, const LLSD& llsd)
return s;
}
+
+//dirty little zippers -- yell at davep if these are horrid
+
+//return a string containing gzipped bytes of binary serialized LLSD
+// VERY inefficient -- creates several copies of LLSD block in memory
+std::string zip_llsd(LLSD& data)
+{
+ std::stringstream llsd_strm;
+
+ LLSDSerialize::serialize(data, llsd_strm, LLSDSerialize::LLSD_BINARY);
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+
+ S32 ret = deflateInit(&strm, Z_BEST_COMPRESSION);
+ if (ret != Z_OK)
+ {
+ llwarns << "Failed to compress LLSD block." << llendl;
+ return std::string();
+ }
+
+ std::string source = llsd_strm.str();
+
+ strm.avail_in = source.size();
+ strm.next_in = (U8*) source.data();
+ U8* output = new U8[strm.avail_in];
+ strm.avail_out = strm.avail_in;
+ strm.next_out = output;
+ ret = deflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END)
+ {
+ delete [] output;
+ llwarns << "Failed to compress LLSD block." << llendl;
+ return std::string();
+ }
+
+ std::string::size_type size = source.size()-strm.avail_out;
+
+ std::string result((char*) output, size);
+ deflateEnd(&strm);
+ delete [] output;
+
+ return result;
+}
+
+//decompress a block of LLSD from provided istream
+// not very efficient -- creats a copy of decompressed LLSD block in memory
+// and deserializes from that copy using LLSDSerialize
+bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
+{
+ U8* result = NULL;
+ U32 cur_size = 0;
+ z_stream strm;
+
+ const U32 CHUNK = 65536;
+
+ U8 *in = new U8[size];
+ is.read((char*) in, size);
+
+ U8 out[CHUNK];
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = size;
+ strm.next_in = in;
+
+ S32 ret = inflateInit(&strm);
+
+ if (ret != Z_OK)
+ {
+ llerrs << "WTF?" << llendl;
+ }
+
+ do
+ {
+ strm.avail_out = CHUNK;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR)
+ {
+ inflateEnd(&strm);
+ free(result);
+ delete [] in;
+ return false;
+ }
+
+ switch (ret)
+ {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&strm);
+ free(result);
+ delete [] in;
+ return false;
+ break;
+ }
+
+ U32 have = CHUNK-strm.avail_out;
+
+ result = (U8*) realloc(result, cur_size + have);
+ memcpy(result+cur_size, out, have);
+ cur_size += have;
+
+ } while (strm.avail_out == 0);
+
+ inflateEnd(&strm);
+ delete [] in;
+
+ if (ret != Z_STREAM_END)
+ {
+ free(result);
+ return false;
+ }
+
+ //result now points to the decompressed LLSD block
+ {
+ std::string res_str((char*) result, cur_size);
+ std::istringstream istr(res_str);
+
+ if (!LLSDSerialize::deserialize(data, istr, cur_size))
+ {
+ llwarns << "Failed to unzip LLSD block" << llendl;
+ free(result);
+ return false;
+ }
+ }
+
+ free(result);
+ return true;
+}
+
+
+
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 2f2b292189..390eaca783 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -796,4 +796,8 @@ public:
}
};
+//dirty little zip functions -- yell at davep
+LL_COMMON_API std::string zip_llsd(LLSD& data);
+LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
+
#endif // LL_LLSDSERIALIZE_H
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 37370e44e7..0385569a02 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -62,6 +62,12 @@
//
//----------------------------------------------------------------------------
+#if !LL_DARWIN
+U32 ll_thread_local sThreadID = 0;
+#endif
+
+U32 LLThread::sIDIter = 0;
+
//
// Handed to the APR thread creation function
//
@@ -72,10 +78,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
// Set thread state to running
threadp->mStatus = RUNNING;
+#if !LL_DARWIN
+ sThreadID = threadp->mID;
+#endif
+
// Run the user supplied function
threadp->run();
- llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl;
+ //llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl;
// We're done with the run function, this thread is done executing now.
threadp->mStatus = STOPPED;
@@ -90,6 +100,8 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
mAPRThreadp(NULL),
mStatus(STOPPED)
{
+ mID = ++sIDIter;
+
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
if (poolp)
{
@@ -273,7 +285,7 @@ void LLThread::wakeLocked()
//============================================================================
LLMutex::LLMutex(apr_pool_t *poolp) :
- mAPRMutexp(NULL)
+ mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
{
//if (poolp)
//{
@@ -305,7 +317,18 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
+#if LL_DARWIN
+ if (mLockingThread == LLThread::currentID())
+#else
+ if (mLockingThread == sThreadID)
+#endif
+ { //redundant lock
+ mCount++;
+ return;
+ }
+
apr_thread_mutex_lock(mAPRMutexp);
+
#if MUTEX_DEBUG
// Have to have the lock before we can access the debug info
U32 id = LLThread::currentID();
@@ -313,10 +336,22 @@ void LLMutex::lock()
llerrs << "Already locked in Thread: " << id << llendl;
mIsLocked[id] = TRUE;
#endif
+
+#if LL_DARWIN
+ mLockingThread = LLThread::currentID();
+#else
+ mLockingThread = sThreadID;
+#endif
}
void LLMutex::unlock()
{
+ if (mCount > 0)
+ { //not the root unlock
+ mCount--;
+ return;
+ }
+
#if MUTEX_DEBUG
// Access the debug info while we have the lock
U32 id = LLThread::currentID();
@@ -324,6 +359,8 @@ void LLMutex::unlock()
llerrs << "Not locked in Thread: " << id << llendl;
mIsLocked[id] = FALSE;
#endif
+
+ mLockingThread = NO_THREAD;
apr_thread_mutex_unlock(mAPRMutexp);
}
@@ -341,6 +378,11 @@ bool LLMutex::isLocked()
}
}
+U32 LLMutex::lockingThread() const
+{
+ return mLockingThread;
+}
+
//============================================================================
LLCondition::LLCondition(apr_pool_t *poolp) :
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index dbb8ec5231..0dc3e0b694 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -41,8 +41,17 @@ class LLThread;
class LLMutex;
class LLCondition;
+#if LL_WINDOWS
+#define ll_thread_local __declspec(thread)
+#else
+#define ll_thread_local __thread
+#endif
+
class LL_COMMON_API LLThread
{
+private:
+ static U32 sIDIter;
+
public:
typedef enum e_thread_status
{
@@ -83,6 +92,8 @@ public:
apr_pool_t *getAPRPool() { return mAPRPoolp; }
LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
+ U32 getID() const { return mID; }
+
private:
BOOL mPaused;
@@ -97,6 +108,7 @@ protected:
apr_pool_t *mAPRPoolp;
BOOL mIsLocalPool;
EThreadStatus mStatus;
+ U32 mID;
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
@@ -134,17 +146,27 @@ protected:
class LL_COMMON_API LLMutex
{
public:
+ typedef enum
+ {
+ NO_THREAD = 0xFFFFFFFF
+ } e_locking_thread;
+
LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
virtual ~LLMutex();
void lock(); // blocks
void unlock();
bool isLocked(); // non-blocking, but does do a lock/unlock so not free
+ U32 lockingThread() const; //get ID of locking thread
protected:
apr_thread_mutex_t *mAPRMutexp;
+ mutable U32 mCount;
+ mutable U32 mLockingThread;
+
apr_pool_t *mAPRPoolp;
BOOL mIsLocalPool;
+
#if MUTEX_DEBUG
std::map<U32, BOOL> mIsLocked;
#endif
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 1a5678dde1..6eead924da 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -55,7 +55,8 @@ enum EDragAndDropType
DAD_ANIMATION = 12,
DAD_GESTURE = 13,
DAD_LINK = 14,
- DAD_COUNT = 15, // number of types in this enum
+ DAD_MESH = 15,
+ DAD_COUNT = 16, // number of types in this enum
};
// Reasons for drags to be denied.