Improved the support for no pre compile, and configuring the number of threads in the DatabasePager.

This commit is contained in:
Robert Osfield 2008-10-26 22:22:38 +00:00
parent 1cb2fc259e
commit 0ff3f48693
7 changed files with 205 additions and 76 deletions

View File

@ -183,6 +183,18 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
void setSerializeDrawDispatch(bool serializeDrawDispatch) { _serializeDrawDispatch = serializeDrawDispatch; }
bool getSerializeDrawDispatch() const { return _serializeDrawDispatch; }
/** Set the hint for the total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/
void setNumOfDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; }
/** Get the hint for total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/
unsigned int getNumOfDatabaseThreadsHint() const { return _numDatabaseThreadsHint; }
/** Set the hint for number of threads in the DatbasePager to dedicate to reading http requests.*/
void setNumOfHttpDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; }
/** Get the hint for number of threads in the DatbasePager dedicated to reading http requests.*/
unsigned int getNumOfHttpDatabaseThreadsHint() const { return _numHttpDatabaseThreadsHint; }
protected:
@ -220,6 +232,9 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
bool _compileContextsHint;
bool _serializeDrawDispatch;
unsigned int _numDatabaseThreadsHint;
unsigned int _numHttpDatabaseThreadsHint;
};
}

View File

@ -114,6 +114,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
Mode _mode;
std::string _name;
};
void setUpThreads(unsigned int totalNumThreads=2, unsigned int numHttpThreads=1);
unsigned int addDatabaseThread(DatabaseThread::Mode mode, const std::string& name);
DatabaseThread* getDatabaseThread(unsigned int i) { return _databaseThreads[i].get(); }

View File

@ -30,9 +30,9 @@ using namespace osg;
// static cache of deleted buffer object lists which can only
// by completely deleted once the appropriate OpenGL context
// is set. Used osg::BufferObject::deleteDisplayList(..) and flushDeletedBufferObjects(..) below.
typedef std::multimap<unsigned int,GLuint> DisplayListMap;
typedef osg::buffered_object<DisplayListMap> DeletedBufferObjectCache;
// is set. Used osg::BufferObject::deleteBufferObject(..) and flushDeletedBufferObjects(..) below.
typedef std::multimap<unsigned int,GLuint> BufferObjectMap;
typedef osg::buffered_object<BufferObjectMap> DeletedBufferObjectCache;
static OpenThreads::Mutex s_mutex_deletedBufferObjectCache;
static DeletedBufferObjectCache s_deletedBufferObjectCache;
@ -44,7 +44,7 @@ void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache);
// insert the globj into the cache for the appropriate context.
s_deletedBufferObjectCache[contextID].insert(DisplayListMap::value_type(0,globj));
s_deletedBufferObjectCache[contextID].insert(BufferObjectMap::value_type(0,globj));
}
}
@ -65,9 +65,9 @@ void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*cur
unsigned int noDeleted = 0;
DisplayListMap& dll = s_deletedBufferObjectCache[contextID];
BufferObjectMap& dll = s_deletedBufferObjectCache[contextID];
DisplayListMap::iterator ditr=dll.begin();
BufferObjectMap::iterator ditr=dll.begin();
for(;
ditr!=dll.end() && elapsedTime<availableTime;
++ditr)
@ -78,7 +78,7 @@ void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*cur
}
if (ditr!=dll.begin()) dll.erase(dll.begin(),ditr);
if (noDeleted!=0) notify(osg::INFO)<<"Number VBOs deleted = "<<noDeleted<<std::endl;
// if (noDeleted!=0) notify(osg::NOTICE)<<"Number VBOs deleted = "<<noDeleted<<" BO's left"<<dll.size()<<std::endl;
}
availableTime -= elapsedTime;
@ -87,7 +87,7 @@ void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*cur
void BufferObject::discardDeletedBufferObjects(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache);
DisplayListMap& dll = s_deletedBufferObjectCache[contextID];
BufferObjectMap& dll = s_deletedBufferObjectCache[contextID];
dll.clear();
}

View File

@ -74,6 +74,9 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
_compileContextsHint = vs._compileContextsHint;
_serializeDrawDispatch = vs._serializeDrawDispatch;
_numDatabaseThreadsHint = vs._numDatabaseThreadsHint;
_numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint;
}
void DisplaySettings::merge(const DisplaySettings& vs)
@ -92,6 +95,9 @@ void DisplaySettings::merge(const DisplaySettings& vs)
if (vs._compileContextsHint) _compileContextsHint = vs._compileContextsHint;
if (vs._serializeDrawDispatch) _serializeDrawDispatch = vs._serializeDrawDispatch;
if (vs._numDatabaseThreadsHint>_numDatabaseThreadsHint) _numDatabaseThreadsHint = vs._numDatabaseThreadsHint;
if (vs._numHttpDatabaseThreadsHint>_numHttpDatabaseThreadsHint) _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint;
}
void DisplaySettings::setDefaults()
@ -133,6 +139,9 @@ void DisplaySettings::setDefaults()
_compileContextsHint = false;
_serializeDrawDispatch = true;
_numDatabaseThreadsHint = 2;
_numHttpDatabaseThreadsHint = 1;
}
void DisplaySettings::setMaxNumberOfGraphicsContexts(unsigned int num)
@ -169,6 +178,8 @@ static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");
static ApplicationUsageProxy DisplaySetting_e13(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_COMPIlE_CONTEXTS <mode>","OFF | ON Enable/disable the use a backgrouind compile contexts and threads.");
static ApplicationUsageProxy DisplaySetting_e14(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SERIALIZE_DRAW_DISPATCH <mode>","OFF | ON Enable/disable the use a muetx to serialize the draw dispatch when there are multiple graphics threads.");
static ApplicationUsageProxy DisplaySetting_e15(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_NUM_DATABASE_THREADS <int>","Set the hint for the total number of threads to set up in the DatabasePager.");
static ApplicationUsageProxy DisplaySetting_e16(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_NUM_HTTP_DATABASE_THREADS <int>","Set the hint for the total number of threads dedicated to http requests to set up in the DatabasePager.");
void DisplaySettings::readEnvironmentalVariables()
{
@ -351,7 +362,15 @@ void DisplaySettings::readEnvironmentalVariables()
}
}
if( (ptr = getenv("OSG_NUM_DATABASE_THREADS")) != 0)
{
_numDatabaseThreadsHint = atoi(ptr);
}
if( (ptr = getenv("OSG_NUM_HTTP_DATABASE_THREADS")) != 0)
{
_numHttpDatabaseThreadsHint = atoi(ptr);
}
}
void DisplaySettings::readCommandLine(ArgumentParser& arguments)
@ -435,4 +454,6 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments)
else if (str=="OFF") _serializeDrawDispatch = false;
}
while(arguments.read("--num-db-threads",_numDatabaseThreadsHint)) {}
while(arguments.read("--num-http-threads",_numHttpDatabaseThreadsHint)) {}
}

View File

@ -537,7 +537,7 @@ void DatabasePager::DatabaseThread::run()
Registry::instance()->readNode(databaseRequest->_fileName, databaseRequest->_loadOptions.get(), false);
if (rr.validNode()) databaseRequest->_loadedModel = rr.getNode();
if (rr.error()) osg::notify(osg::WARN) << rr.message() << std::endl;
if (rr.error()) osg::notify(osg::WARN)<<"Error in reading file "<<databaseRequest->_fileName<<" : "<<rr.message() << std::endl;
if (databaseRequest->_loadedModel.valid() &&
osgDB::containsServerAddress(databaseRequest->_fileName) &&
@ -566,21 +566,62 @@ void DatabasePager::DatabaseThread::run()
bool loadedObjectsNeedToBeCompiled = false;
if (databaseRequest->_loadedModel.valid())
{
{
databaseRequest->_loadedModel->getBound();
osg::NodePath nodePath;
osg::NodePathList nodePathList = groupForAddingLoadedSubgraph->getParentalNodePaths();
if (!nodePathList.empty()) nodePath = nodePathList.front();
nodePath.push_back(groupForAddingLoadedSubgraph.get());
#if 1
// force a compute of the loaded model's bounding volume, so that when the subgraph
// merged with the main scene graph and large computeBound() isn't incurred.
ActiveGraphicsContexts::iterator itr = _pager->_activeGraphicsContexts.begin();
DataToCompile& dtc = databaseRequest->_dataToCompileMap[*itr];
++itr;
// find all the compileable rendering objects
DatabasePager::FindCompileableGLObjectsVisitor frov(dtc,
_pager->_changeAutoUnRef, _pager->_valueAutoUnRef,
_pager->_changeAnisotropy, _pager->_valueAnisotropy,
_pager->_drawablePolicy,
_pager);
// push the soon to be parent on the nodepath of the NodeVisitor so that
// during traversal one can test for where it'll be in the overall scene graph
for(osg::NodePath::iterator nitr = nodePath.begin();
nitr != nodePath.end();
++nitr)
{
frov.pushOntoNodePath(*nitr);
}
databaseRequest->_loadedModel->accept(frov);
if (_pager->_doPreCompile &&
!_pager->_activeGraphicsContexts.empty())
{
if (!dtc.first.empty() || !dtc.second.empty())
{
loadedObjectsNeedToBeCompiled = true;
// copy the objects from the compile list to the other graphics context list.
for(;
itr != _pager->_activeGraphicsContexts.end();
++itr)
{
databaseRequest->_dataToCompileMap[*itr] = dtc;
}
}
}
#else
if (_pager->_doPreCompile &&
!_pager->_activeGraphicsContexts.empty())
{
// force a compute of the loaded model's bounding volume, so that when the subgraph
// merged with the main scene graph and large computeBound() isn't incurred.
databaseRequest->_loadedModel->getBound();
ActiveGraphicsContexts::iterator itr = _pager->_activeGraphicsContexts.begin();
DataToCompile& dtc = databaseRequest->_dataToCompileMap[*itr];
@ -639,6 +680,7 @@ void DatabasePager::DatabaseThread::run()
//osg::notify(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
}
}
#endif
// move the databaseRequest from the front of the fileRequest to the end of
// dataToCompile or dataToMerge lists.
@ -734,10 +776,7 @@ void DatabasePager::DatabaseThread::run()
} while (!testCancel() && !_done);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DatabasePager
//
DatabasePager::DatabasePager()
{
//osg::notify(osg::INFO)<<"Constructing DatabasePager()"<<std::endl;
@ -911,21 +950,10 @@ DatabasePager::DatabasePager()
_dataToCompileList = new RequestQueue;
_dataToMergeList = new RequestQueue;
setUpThreads(
osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(),
osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint());
#if 0
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ALL_REQUESTS,"HANDLE_ALL_REQUESTS"));
#else
#if 1
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 0"));
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 1"));
#else
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 0"));
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 1"));
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 2"));
_databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 3"));
#endif
#endif
}
DatabasePager::DatabasePager(const DatabasePager& rhs)
@ -1000,6 +1028,53 @@ DatabasePager* DatabasePager::create()
new DatabasePager;
}
void DatabasePager::setUpThreads(unsigned int totalNumThreads, unsigned int numHttpThreads)
{
_databaseThreads.clear();
unsigned int numGeneralThreads = numHttpThreads < totalNumThreads ?
totalNumThreads - numHttpThreads :
1;
if (numHttpThreads==0)
{
for(unsigned int i=0; i<numGeneralThreads; ++i)
{
addDatabaseThread(DatabaseThread::HANDLE_ALL_REQUESTS,"HANDLE_ALL_REQUESTS");
}
}
else
{
for(unsigned int i=0; i<numGeneralThreads; ++i)
{
addDatabaseThread(DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP");
}
for(unsigned int i=0; i<numHttpThreads; ++i)
{
addDatabaseThread(DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP");
}
}
}
unsigned int DatabasePager::addDatabaseThread(DatabaseThread::Mode mode, const std::string& name)
{
osg::notify(osg::INFO)<<"DatabasePager::addDatabaseThread() "<<name<<std::endl;
unsigned int pos = _databaseThreads.size();
DatabaseThread* thread = new DatabaseThread(this, mode,name);
_databaseThreads.push_back(thread);
if (_startThreadCalled)
{
osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"<<std::endl;
thread->startThread();
}
return pos;
}
void DatabasePager::setReleaseDelay(double releaseDelay)
{
_releaseDelay = releaseDelay;
@ -1238,6 +1313,13 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
_done = false;
osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"<<std::endl;
if (_databaseThreads.empty())
{
setUpThreads(
osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(),
osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint());
}
for(DatabaseThreadList::const_iterator dt_itr = _databaseThreads.begin();
dt_itr != _databaseThreads.end();
++dt_itr)
@ -1292,16 +1374,18 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp)
double timeStamp = frameStamp.getReferenceTime();
int frameNumber = frameStamp.getFrameNumber();
// osg::Timer_t before = osg::Timer::instance()->tick();
osg::Timer_t before = osg::Timer::instance()->tick();
RequestQueue::RequestList localFileLoadedList;
// get the dat for the _dataToCompileList, leaving it empty via a std::vector<>.swap.
// get the data for the _dataToCompileList, leaving it empty via a std::vector<>.swap.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeList->_requestMutex);
localFileLoadedList.swap(_dataToMergeList->_requestList);
}
osg::Timer_t mid = osg::Timer::instance()->tick();
// add the loaded data into the scene graph.
for(RequestQueue::RequestList::iterator itr=localFileLoadedList.begin();
itr!=localFileLoadedList.end();
@ -1338,7 +1422,7 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp)
group->addChild(databaseRequest->_loadedModel.get());
osg::notify(osg::INFO)<<"merged subgraph"<<databaseRequest->_fileName<<" after "<<databaseRequest->_numOfRequests<<" requests and time="<<(timeStamp-databaseRequest->_timestampFirstRequest)*1000.0<<std::endl;
// osg::notify(osg::NOTICE)<<"merged subgraph"<<databaseRequest->_fileName<<" after "<<databaseRequest->_numOfRequests<<" requests and time="<<(timeStamp-databaseRequest->_timestampFirstRequest)*1000.0<<std::endl;
double timeToMerge = timeStamp-databaseRequest->_timestampFirstRequest;
@ -1355,7 +1439,12 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp)
// osg::notify(osg::NOTICE)<<"curr = "<<timeToMerge<<" min "<<getMinimumTimeToMergeTile()*1000.0<<" max = "<<getMaximumTimeToMergeTile()*1000.0<<" average = "<<getAverageTimToMergeTiles()*1000.0<<std::endl;
}
// osg::notify(osg::NOTICE)<<"Done DatabasePager::addLoadedDataToSceneGraph"<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms objects"<<localFileLoadedList.size()<<std::endl;
osg::Timer_t last = osg::Timer::instance()->tick();
osg::notify(osg::INFO)<<"Done DatabasePager::addLoadedDataToSceneGraph"<<
osg::Timer::instance()->delta_m(before,mid)<<"ms,\t"<<
osg::Timer::instance()->delta_m(mid,last)<<"ms"<<
" objects"<<localFileLoadedList.size()<<std::endl<<std::endl;
}
@ -1413,8 +1502,6 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt
osg::Timer_t startTick = osg::Timer::instance()->tick();
#if 1
unsigned int numPagedLODs = _activePagedLODList.size() + _inactivePagedLODList.size();
@ -1431,7 +1518,7 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt
if (_releaseDelay!=DBL_MAX)
{
plod->releaseGLObjects();
osg::notify(osg::INFO)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<<std::endl;
osg::notify(osg::NOTICE)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<<std::endl;
}
_inactivePagedLODList.push_back(plod);
@ -1468,41 +1555,6 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt
PagedLODList& pagedLODList = _inactivePagedLODList;
#else
unsigned int inactivePLOD = 0;
unsigned int activePLOD = 0;
// iterate through the PagedLOD list moving all newly traversed nodes to end of list
// leaving inactive ones in place, so they in effect shuffle to the front, with the least
// recently traversed placed at the front
unsigned int numPagedLODs = _activePagedLODList.size();
PagedLODList::iterator itr = _activePagedLODList.begin();
for(unsigned int numIterations = 0;
numIterations < numPagedLODs;
++numIterations)
{
osg::PagedLOD* plod = itr->get();
int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal();
if (delta>1)
{
++inactivePLOD;
++itr;
}
else
{
++activePLOD;
_activePagedLODList.push_back(plod);
itr = _activePagedLODList.erase(itr);
}
}
PagedLODList& pagedLODList = _activePagedLODList;
#endif
osg::Timer_t end_a_Tick = osg::Timer::instance()->tick();
double time_a = osg::Timer::instance()->delta_m(startTick,end_a_Tick);
@ -1559,11 +1611,12 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt
s_total_time_stage_b += time_b;
if (s_total_max_stage_b<time_b) s_total_max_stage_b = time_b;
bool updateBlock = false;
if (!childrenRemoved.empty())
{
bool updateBlock = false;
// pass the objects across to the database pager delete list
if (_deleteRemovedSubgraphsInDatabaseThread)
{

View File

@ -350,6 +350,26 @@ BEGIN_OBJECT_REFLECTOR(osg::DisplaySettings)
__bool__getSerializeDrawDispatch,
"",
"");
I_Method1(void, setNumOfDatabaseThreadsHint, IN, unsigned int, numThreads,
Properties::NON_VIRTUAL,
__void__setNumOfDatabaseThreadsHint__unsigned_int,
"Set the hint for the total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads. ",
"");
I_Method0(unsigned int, getNumOfDatabaseThreadsHint,
Properties::NON_VIRTUAL,
__unsigned_int__getNumOfDatabaseThreadsHint,
"Get the hint for total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads. ",
"");
I_Method1(void, setNumOfHttpDatabaseThreadsHint, IN, unsigned int, numThreads,
Properties::NON_VIRTUAL,
__void__setNumOfHttpDatabaseThreadsHint__unsigned_int,
"Set the hint for number of threads in the DatbasePager to dedicate to reading http requests. ",
"");
I_Method0(unsigned int, getNumOfHttpDatabaseThreadsHint,
Properties::NON_VIRTUAL,
__unsigned_int__getNumOfHttpDatabaseThreadsHint,
"Get the hint for number of threads in the DatbasePager dedicated to reading http requests. ",
"");
I_StaticMethod0(osg::DisplaySettings *, instance,
__DisplaySettings_P1__instance_S,
"Maintain a DisplaySettings singleton for objects to query at runtime. ",
@ -405,6 +425,12 @@ BEGIN_OBJECT_REFLECTOR(osg::DisplaySettings)
I_SimpleProperty(unsigned int, NumMultiSamples,
0,
__void__setNumMultiSamples__unsigned_int);
I_SimpleProperty(unsigned int, NumOfDatabaseThreadsHint,
0,
__void__setNumOfDatabaseThreadsHint__unsigned_int);
I_SimpleProperty(unsigned int, NumOfHttpDatabaseThreadsHint,
0,
__void__setNumOfHttpDatabaseThreadsHint__unsigned_int);
I_SimpleProperty(bool, RGB,
__bool__getRGB,
__void__setRGB__bool);

View File

@ -99,6 +99,16 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
__void__clear,
"Clear all internally cached structures. ",
"");
I_MethodWithDefaults2(void, setUpsThreads, IN, unsigned int, totalNumThreads, 2, IN, unsigned int, numHttpThreads, 1,
Properties::NON_VIRTUAL,
__void__setUpsThreads__unsigned_int__unsigned_int,
"",
"");
I_Method2(unsigned int, addDatabaseThread, IN, osgDB::DatabasePager::DatabaseThread::Mode, mode, IN, const std::string &, name,
Properties::NON_VIRTUAL,
__unsigned_int__addDatabaseThread__DatabaseThread_Mode__C5_std_string_R1,
"",
"");
I_Method1(osgDB::DatabasePager::DatabaseThread *, getDatabaseThread, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__DatabaseThread_P1__getDatabaseThread__unsigned_int,