1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-513 use a single funcor per thread. ThreadPool was doing one at a time anyway, but in a convpluted way that made it easier to add more if wanted. But it was expensive. Cleanup and polish.

This commit is contained in:
David Hall
2017-02-17 09:44:32 -06:00
parent 776add46dc
commit 87a679e6eb
13 changed files with 305 additions and 296 deletions

View File

@ -28,7 +28,6 @@
using namespace std; using namespace std;
#include "joblist.h" #include "joblist.h"
#include "calpontsystemcatalog.h" #include "calpontsystemcatalog.h"
using namespace execplan; using namespace execplan;
@ -73,23 +72,26 @@ JobList::JobList(bool isEM) :
JobList::~JobList() JobList::~JobList()
{ {
vector<boost::thread *> joiners;
// boost::thread *tmp;
try try
{ {
if (fIsRunning) if (fIsRunning)
{ {
JobStepVector::iterator iter;
JobStepVector::iterator end;
#if 0 #if 0
// This logic creates a set of threads to wind down the query
vector<uint64_t> joiners;
joiners.reserve(20);
NullStep nullStep; // For access to the static jobstepThreadPool.
JobStepVector::iterator iter;
JobStepVector::iterator end;
iter = fQuery.begin(); iter = fQuery.begin();
end = fQuery.end(); end = fQuery.end();
// Wait for all the query steps to finish // Wait for all the query steps to finish
while (iter != end) while (iter != end)
{ {
tmp = new boost::thread(JSJoiner(iter->get())); joiners.push_back(nullStep.jobstepThreadPool.invoke(JSJoiner(iter->get())));
joiners.push_back(tmp);
++iter; ++iter;
} }
@ -99,17 +101,15 @@ JobList::~JobList()
// wait for the projection steps // wait for the projection steps
while (iter != end) while (iter != end)
{ {
tmp = new boost::thread(JSJoiner(iter->get())); joiners.push_back(nullStep.jobstepThreadPool.invoke(JSJoiner(iter->get())));
joiners.push_back(tmp);
++iter; ++iter;
} }
for (uint32_t i = 0; i < joiners.size(); i++) { nullStep.jobstepThreadPool.join(joiners);
joiners[i]->join();
delete joiners[i];
}
#endif #endif
// Stop all the query steps // This logic stops the query steps one at a time
JobStepVector::iterator iter;
JobStepVector::iterator end;
end = fQuery.end(); end = fQuery.end();
for (iter = fQuery.begin(); iter != end; ++iter) for (iter = fQuery.begin(); iter != end; ++iter)
{ {

View File

@ -330,6 +330,20 @@ public:
virtual bool deliverStringTableRowGroup() const = 0; virtual bool deliverStringTableRowGroup() const = 0;
}; };
class NullStep : public JobStep
{
public:
/** @brief virtual void Run method
*/
virtual void run(){}
/** @brief virtual void join method
*/
virtual void join(){}
/** @brief virtual string toString method
*/
virtual const std::string toString() const {return "NullStep";}
};
// calls rhs->toString() // calls rhs->toString()
std::ostream& operator<<(std::ostream& os, const JobStep* rhs); std::ostream& operator<<(std::ostream& os, const JobStep* rhs);

View File

@ -134,9 +134,9 @@ pDictionaryScan::pDictionaryScan(
sendWaiting(false), sendWaiting(false),
ridCount(0), ridCount(0),
ridList(0), ridList(0),
colType(ct),
pThread(0), pThread(0),
cThread(0), cThread(0),
colType(ct),
fScanLbidReqLimit(jobInfo.rm->getJlScanLbidReqLimit()), fScanLbidReqLimit(jobInfo.rm->getJlScanLbidReqLimit()),
fScanLbidReqThreshold(jobInfo.rm->getJlScanLbidReqThreshold()), fScanLbidReqThreshold(jobInfo.rm->getJlScanLbidReqThreshold()),
fStopSending(false), fStopSending(false),

View File

@ -775,9 +775,7 @@ void TupleUnion::run()
void TupleUnion::join() void TupleUnion::join()
{ {
uint32_t i;
mutex::scoped_lock lk(jlLock); mutex::scoped_lock lk(jlLock);
Uniquer_t::iterator it;
if (joinRan) if (joinRan)
return; return;

View File

@ -340,6 +340,7 @@ DDLProcessor::DDLProcessor( int packageMaxThreads, int packageWorkQueueSize )
{ {
fDdlPackagepool.setMaxThreads(fPackageMaxThreads); fDdlPackagepool.setMaxThreads(fPackageMaxThreads);
fDdlPackagepool.setQueueSize(fPackageWorkQueueSize); fDdlPackagepool.setQueueSize(fPackageWorkQueueSize);
fDdlPackagepool.setName("DdlPackagepool");
csc = CalpontSystemCatalog::makeCalpontSystemCatalog(); csc = CalpontSystemCatalog::makeCalpontSystemCatalog();
csc->identity(CalpontSystemCatalog::EC); csc->identity(CalpontSystemCatalog::EC);
string teleServerHost(config::Config::makeConfig()->getConfig("QueryTele", "Host")); string teleServerHost(config::Config::makeConfig()->getConfig("QueryTele", "Host"));

View File

@ -558,8 +558,23 @@ int main(int argc, char* argv[])
} }
DMLServer dmlserver(serverThreads, serverQueueSize,&dbrm); DMLServer dmlserver(serverThreads, serverQueueSize,&dbrm);
ResourceManager *rm = ResourceManager::instance();
//set ACTIVE state // jobstepThreadPool is used by other processes. We can't call
// resourcemanaager (rm) functions during the static creation of threadpool
// because rm has a "isExeMgr" flag that is set upon creation (rm is a singleton).
// From the pools perspective, it has no idea if it is ExeMgr doing the
// creation, so it has no idea which way to set the flag. So we set the max here.
JobStep::jobstepThreadPool.setMaxThreads(rm->getJLThreadPoolSize());
JobStep::jobstepThreadPool.setName("DMLProcJobList");
// if (rm->getJlThreadPoolDebug() == "Y" || rm->getJlThreadPoolDebug() == "y")
// {
// JobStep::jobstepThreadPool.setDebug(true);
// JobStep::jobstepThreadPool.invoke(ThreadPoolMonitor(&JobStep::jobstepThreadPool));
// }
//set ACTIVE state
try try
{ {
oam.processInitComplete("DMLProc", ACTIVE); oam.processInitComplete("DMLProc", ACTIVE);
@ -567,7 +582,6 @@ int main(int argc, char* argv[])
catch (...) catch (...)
{ {
} }
ResourceManager *rm = ResourceManager::instance();
Dec = DistributedEngineComm::instance(rm); Dec = DistributedEngineComm::instance(rm);
#ifndef _MSC_VER #ifndef _MSC_VER

View File

@ -1130,6 +1130,7 @@ DMLServer::DMLServer(int packageMaxThreads, int packageWorkQueueSize, DBRM* dbrm
fDmlPackagepool.setMaxThreads(fPackageMaxThreads); fDmlPackagepool.setMaxThreads(fPackageMaxThreads);
fDmlPackagepool.setQueueSize(fPackageWorkQueueSize); fDmlPackagepool.setQueueSize(fPackageWorkQueueSize);
fDmlPackagepool.setName("DmlPackagepool");
} }
void DMLServer::start() void DMLServer::start()

View File

@ -24,7 +24,7 @@ using namespace std;
using namespace joblist; using namespace joblist;
using namespace messageqcpp; using namespace messageqcpp;
threadpool::ThreadPool FEMsgHandler::threadPool(100,200); threadpool::ThreadPool FEMsgHandler::threadPool(50,100);
namespace { namespace {
@ -52,15 +52,14 @@ FEMsgHandler::FEMsgHandler(boost::shared_ptr<JobList> j, IOSocket *s) :
FEMsgHandler::~FEMsgHandler() FEMsgHandler::~FEMsgHandler()
{ {
stop(); stop();
// thr.join(); threadPool.join(thr);
boost::unique_lock<boost::mutex> lk(joinMutex);
} }
void FEMsgHandler::start() void FEMsgHandler::start()
{ {
if (!running) { if (!running) {
running = true; running = true;
threadPool.invoke(Runner(this)); thr = threadPool.invoke(Runner(this));
} }
} }
@ -109,7 +108,6 @@ bool FEMsgHandler::aborted()
void FEMsgHandler::threadFcn() void FEMsgHandler::threadFcn()
{ {
int err = 0; int err = 0;
boost::unique_lock<boost::mutex> lk(joinMutex);
int connectionNum = sock->getConnectionNum(); int connectionNum = sock->getConnectionNum();
/* This waits for the next readable event on sock. An abort is signaled /* This waits for the next readable event on sock. An abort is signaled

View File

@ -37,18 +37,14 @@ public:
void threadFcn(); void threadFcn();
static threadpool::ThreadPool threadPool;
private: private:
bool die, running, sawData; bool die, running, sawData;
messageqcpp::IOSocket *sock; messageqcpp::IOSocket *sock;
boost::shared_ptr<joblist::JobList> jl; boost::shared_ptr<joblist::JobList> jl;
boost::mutex mutex; boost::mutex mutex;
// boost::thread thr; uint64_t thr;
static threadpool::ThreadPool threadPool;
// Because we can't join() a thread from a thread pool, threadFcn will
// unlock when it exits and the destructor can block until the thread is done.
boost::mutex joinMutex;
}; };
#endif /* FEMSGHANDLER_H_ */ #endif /* FEMSGHANDLER_H_ */

View File

@ -515,7 +515,7 @@ public:
SJLP jl; SJLP jl;
bool incSessionThreadCnt = true; bool incSessionThreadCnt = true;
bool selfJoin = false; bool selfJoin = false;
bool tryTuples = false; bool tryTuples = false;
bool usingTuples = false; bool usingTuples = false;
bool stmtCounted = false; bool stmtCounted = false;
@ -1393,19 +1393,18 @@ int main(int argc, char* argv[])
} }
} }
// It's possible that PM modules use this threadpool. Only ExeMgr creates // jobstepThreadPool is used by other processes. We can't call
// massive amounts of threads and needs to be settable. It's also possible that // resourcemanaager (rm) functions during the static creation of threadpool
// other process on this UM module use this threadpool. In this case, they share. // because rm has a "isExeMgr" flag that is set upon creation (rm is a singleton).
// We can't call rm functions during the static creation because rm has a isExeMgr // From the pools perspective, it has no idea if it is ExeMgr doing the
// flag that is set upon first creation. For the pool, who has no idea if it is ExeMgr, // creation, so it has no idea which way to set the flag. So we set the max here.
// to create the singleton rm would be wrong, no matter which way we set the flag.
JobStep::jobstepThreadPool.setMaxThreads(rm->getJLThreadPoolSize()); JobStep::jobstepThreadPool.setMaxThreads(rm->getJLThreadPoolSize());
JobStep::jobstepThreadPool.setName("ExeMgr"); JobStep::jobstepThreadPool.setName("ExeMgrJobList");
if (rm->getJlThreadPoolDebug() == "Y" || rm->getJlThreadPoolDebug() == "y") // if (rm->getJlThreadPoolDebug() == "Y" || rm->getJlThreadPoolDebug() == "y")
{ // {
JobStep::jobstepThreadPool.setDebug(true); // JobStep::jobstepThreadPool.setDebug(true);
JobStep::jobstepThreadPool.invoke(ThreadPoolMonitor(&JobStep::jobstepThreadPool)); // JobStep::jobstepThreadPool.invoke(ThreadPoolMonitor(&JobStep::jobstepThreadPool));
} // }
int serverThreads = rm->getEmServerThreads(); int serverThreads = rm->getEmServerThreads();
int serverQueueSize = rm->getEmServerQueueSize(); int serverQueueSize = rm->getEmServerQueueSize();
@ -1413,7 +1412,11 @@ int main(int argc, char* argv[])
int pauseSeconds = rm->getEmSecondsBetweenMemChecks(); int pauseSeconds = rm->getEmSecondsBetweenMemChecks();
int priority = rm->getEmPriority(); int priority = rm->getEmPriority();
if (maxPct > 0) FEMsgHandler::threadPool.setMaxThreads(serverThreads);
FEMsgHandler::threadPool.setQueueSize(serverQueueSize);
FEMsgHandler::threadPool.setName("FEMsgHandler");
if (maxPct > 0)
startRssMon(maxPct, pauseSeconds); startRssMon(maxPct, pauseSeconds);
#ifndef _MSC_VER #ifndef _MSC_VER
@ -1448,6 +1451,7 @@ int main(int argc, char* argv[])
} }
threadpool::ThreadPool exeMgrThreadPool(serverThreads, serverQueueSize); threadpool::ThreadPool exeMgrThreadPool(serverThreads, serverQueueSize);
exeMgrThreadPool.setName("ExeMgrServer");
for (;;) for (;;)
{ {
IOSocket ios; IOSocket ios;

View File

@ -2032,6 +2032,7 @@ PrimitiveServer::PrimitiveServer(int serverThreads,
fCacheCount=cacheCount; fCacheCount=cacheCount;
fServerpool.setMaxThreads(fServerThreads); fServerpool.setMaxThreads(fServerThreads);
fServerpool.setQueueSize(fServerQueueSize); fServerpool.setQueueSize(fServerQueueSize);
fServerpool.setName("PrimitiveServer");
fProcessorPool.reset(new threadpool::PriorityThreadPool(fProcessorWeight, highPriorityThreads, fProcessorPool.reset(new threadpool::PriorityThreadPool(fProcessorWeight, highPriorityThreads,
medPriorityThreads, lowPriorityThreads, 0)); medPriorityThreads, lowPriorityThreads, 0));

View File

@ -283,42 +283,28 @@ void ThreadPool::beginThread() throw()
else else
{ {
// Wait no more than 10 minutes // Wait no more than 10 minutes
if (fNeedThread.timed_wait(lock1, timeout) == boost::cv_status::timeout) if (!fNeedThread.timed_wait(lock1, timeout)) // false means it timed out
{ {
if (fThreadCount > fMaxThreads) if (fThreadCount > fMaxThreads)
{ {
--fThreadCount; --fThreadCount;
return; return;
} }
timeout = boost::get_system_time()+boost::posix_time::minutes(10);
} }
} }
} }
else else
{ {
/* Need to tune these magic #s */ // If there's anything waiting, run it
vector<Container_T::iterator> todoList; if (waitingFunctorsSize - fIssued > 0)
int i, num;
Container_T::const_iterator iter;
/* Use num to control how many jobs are issued to a single thread
should you want to batch more than one */
num = (waitingFunctorsSize - fIssued >= 1 ? 1 : 0);
for (i = 0; i < num; i++)
todoList.push_back(fNextFunctor++);
fIssued += num;
// cerr << "got " << num << " jobs." << endl;
// cerr << "got " << num << " jobs. waitingFunctorsSize=" <<
// waitingFunctorsSize << " fIssued=" << fIssued << " fThreadCount=" <<
// fThreadCount << endl;
lock1.unlock();
for (i = 0; i < num; i++)
{ {
Container_T::iterator todo = fNextFunctor++;
++fIssued;
lock1.unlock();
try try
{ {
(*todoList[i]).functor(); todo->functor();
} }
catch (exception &e) catch (exception &e)
{ {
@ -334,18 +320,12 @@ void ThreadPool::beginThread() throw()
ml.logErrorMessage( message ); ml.logErrorMessage( message );
#endif #endif
} }
lock1.lock();
--fIssued;
--waitingFunctorsSize;
fWaitingFunctors.erase(todo);
} }
lock1.lock();
fIssued -= num;
waitingFunctorsSize -= num;
for (i = 0; i < num; i++)
fWaitingFunctors.erase(todoList[i]);
/*
if (waitingFunctorsSize != fWaitingFunctors.size())
cerr << "size mismatch! fake size=" << waitingFunctorsSize <<
" real size=" << fWaitingFunctors.size() << endl;
*/
timeout = boost::get_system_time()+boost::posix_time::minutes(10); timeout = boost::get_system_time()+boost::posix_time::minutes(10);
fThreadAvailable.notify_all(); fThreadAvailable.notify_all();
} }

View File

@ -1,222 +1,224 @@
<!DOCTYPE Project SYSTEM "http://www.slickedit.com/dtd/vse/10.0/vpj.dtd"> <!DOCTYPE Project SYSTEM "http://www.slickedit.com/dtd/vse/10.0/vpj.dtd">
<Project <Project
Version="10.0" Version="10.0"
VendorName="SlickEdit" VendorName="SlickEdit"
TemplateName="GNU C/C++" TemplateName="GNU C/C++"
WorkingDir="."> WorkingDir=".">
<Config <Config
Name="Debug" Name="Debug"
Type="gnuc" Type="gnuc"
DebugCallbackName="gdb" DebugCallbackName="gdb"
Version="1" Version="1"
OutputFile="%bdthreadpool.so" OutputFile="%bdthreadpool.so"
CompilerConfigName="Latest Version"> CompilerConfigName="Latest Version">
<Menu> <Menu>
<Target <Target
Name="Compile" Name="Compile"
MenuCaption="&amp;Compile" MenuCaption="&amp;Compile"
Dialog="_gnuc_options_form Compile" Dialog="_gnuc_options_form Compile"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
OutputExts="*.o" OutputExts="*.o"
SaveOption="SaveCurrent" SaveOption="SaveCurrent"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine='g++ -c %xup %defd -g -o "%bd%n%oe" %i "%f"'/> <Exec CmdLine='g++ -c %xup %defd -g -o "%bd%n%oe" %i "%f"'/>
</Target> </Target>
<Target <Target
Name="Link" Name="Link"
MenuCaption="&amp;Link" MenuCaption="&amp;Link"
ShowOnMenu="Never" ShowOnMenu="Never"
Dialog="_gnuc_options_form Link" Dialog="_gnuc_options_form Link"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveCurrent" SaveOption="SaveCurrent"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine='g++ %xup -g -o "%o" %f %libs -shared -fPIC'/> <Exec CmdLine='g++ %xup -g -o "%o" %f %libs -shared -fPIC'/>
</Target> </Target>
<Target <Target
Name="Build" Name="Build"
MenuCaption="&amp;Build" MenuCaption="&amp;Build"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine="make"/> <Exec CmdLine="make"/>
</Target> </Target>
<Target <Target
Name="Rebuild" Name="Rebuild"
MenuCaption="&amp;Rebuild" MenuCaption="&amp;Rebuild"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="Debug" Name="Debug"
MenuCaption="&amp;Debug" MenuCaption="&amp;Debug"
Dialog="_gnuc_options_form Run/Debug" Dialog="_gnuc_options_form Run/Debug"
BuildFirst="1" BuildFirst="1"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveNone" SaveOption="SaveNone"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="Execute" Name="Execute"
MenuCaption="E&amp;xecute" MenuCaption="E&amp;xecute"
Dialog="_gnuc_options_form Run/Debug" Dialog="_gnuc_options_form Run/Debug"
BuildFirst="1" BuildFirst="1"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="dash" Name="dash"
MenuCaption="-" MenuCaption="-"
Deletable="0"> Deletable="0">
<Exec/> <Exec/>
</Target> </Target>
<Target <Target
Name="GNU C Options" Name="GNU C Options"
MenuCaption="GNU C &amp;Options..." MenuCaption="GNU C &amp;Options..."
ShowOnMenu="HideIfNoCmdLine" ShowOnMenu="HideIfNoCmdLine"
Deletable="0" Deletable="0"
SaveOption="SaveNone"> SaveOption="SaveNone">
<Exec <Exec
CmdLine="gnucoptions" CmdLine="gnucoptions"
Type="Slick-C"/> Type="Slick-C"/>
</Target> </Target>
</Menu> </Menu>
<List Name="GNUC Options"> <List Name="GNUC Options">
<Item <Item
Name="LinkerOutputType" Name="LinkerOutputType"
Value="SharedLibrary"/> Value="SharedLibrary"/>
</List> </List>
</Config> </Config>
<Config <Config
Name="Release" Name="Release"
Type="gnuc" Type="gnuc"
DebugCallbackName="gdb" DebugCallbackName="gdb"
Version="1" Version="1"
OutputFile="%bdthreadpool.so" OutputFile="%bdthreadpool.so"
CompilerConfigName="Latest Version"> CompilerConfigName="Latest Version">
<Menu> <Menu>
<Target <Target
Name="Compile" Name="Compile"
MenuCaption="&amp;Compile" MenuCaption="&amp;Compile"
Dialog="_gnuc_options_form Compile" Dialog="_gnuc_options_form Compile"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
OutputExts="*.o" OutputExts="*.o"
SaveOption="SaveCurrent" SaveOption="SaveCurrent"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine='g++ -c %xup %defd -o "%bd%n%oe" %i "%f"'/> <Exec CmdLine='g++ -c %xup %defd -o "%bd%n%oe" %i "%f"'/>
</Target> </Target>
<Target <Target
Name="Link" Name="Link"
MenuCaption="&amp;Link" MenuCaption="&amp;Link"
ShowOnMenu="Never" ShowOnMenu="Never"
Dialog="_gnuc_options_form Link" Dialog="_gnuc_options_form Link"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveCurrent" SaveOption="SaveCurrent"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine='g++ %xup -o "%o" %f %libs -shared -fPIC'/> <Exec CmdLine='g++ %xup -o "%o" %f %libs -shared -fPIC'/>
</Target> </Target>
<Target <Target
Name="Build" Name="Build"
MenuCaption="&amp;Build" MenuCaption="&amp;Build"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine="make"/> <Exec CmdLine="make"/>
</Target> </Target>
<Target <Target
Name="Rebuild" Name="Rebuild"
MenuCaption="&amp;Rebuild" MenuCaption="&amp;Rebuild"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="Debug" Name="Debug"
MenuCaption="&amp;Debug" MenuCaption="&amp;Debug"
Dialog="_gnuc_options_form Run/Debug" Dialog="_gnuc_options_form Run/Debug"
BuildFirst="1" BuildFirst="1"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveNone" SaveOption="SaveNone"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="Execute" Name="Execute"
MenuCaption="E&amp;xecute" MenuCaption="E&amp;xecute"
Dialog="_gnuc_options_form Run/Debug" Dialog="_gnuc_options_form Run/Debug"
BuildFirst="1" BuildFirst="1"
CaptureOutputWith="ProcessBuffer" CaptureOutputWith="ProcessBuffer"
Deletable="0" Deletable="0"
SaveOption="SaveWorkspaceFiles" SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw"> RunFromDir="%rw">
<Exec CmdLine=""/> <Exec CmdLine=""/>
</Target> </Target>
<Target <Target
Name="dash" Name="dash"
MenuCaption="-" MenuCaption="-"
Deletable="0"> Deletable="0">
<Exec/> <Exec/>
</Target> </Target>
<Target <Target
Name="GNU C Options" Name="GNU C Options"
MenuCaption="GNU C &amp;Options..." MenuCaption="GNU C &amp;Options..."
ShowOnMenu="HideIfNoCmdLine" ShowOnMenu="HideIfNoCmdLine"
Deletable="0" Deletable="0"
SaveOption="SaveNone"> SaveOption="SaveNone">
<Exec <Exec
CmdLine="gnucoptions" CmdLine="gnucoptions"
Type="Slick-C"/> Type="Slick-C"/>
</Target> </Target>
</Menu> </Menu>
<List Name="GNUC Options"> <List Name="GNUC Options">
<Item <Item
Name="LinkerOutputType" Name="LinkerOutputType"
Value="SharedLibrary"/> Value="SharedLibrary"/>
</List> </List>
</Config> </Config>
<Files> <Files>
<Folder <Folder
Name="Source Files" Name="Source Files"
Filters="*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.c++;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl;*.d"> Filters="*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.c++;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl;*.d">
<F N="tdriver.cpp"/> <F N="prioritythreadpool.cpp"/>
<F N="threadpool.cpp"/> <F N="tdriver.cpp"/>
<F N="weightedthreadpool.cpp"/> <F N="threadpool.cpp"/>
<F N="wtp.cpp"/> <F N="weightedthreadpool.cpp"/>
</Folder> <F N="wtp.cpp"/>
<Folder </Folder>
Name="Header Files" <Folder
Filters="*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if"> Name="Header Files"
<F N="threadpool.h"/> Filters="*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if">
<F N="weightedthreadpool.h"/> <F N="prioritythreadpool.h"/>
</Folder> <F N="threadpool.h"/>
<Folder <F N="weightedthreadpool.h"/>
Name="Resource Files" </Folder>
Filters="*.ico;*.cur;*.dlg"/> <Folder
<Folder Name="Resource Files"
Name="Bitmaps" Filters="*.ico;*.cur;*.dlg"/>
Filters="*.bmp"/> <Folder
<Folder Name="Bitmaps"
Name="Other Files" Filters="*.bmp"/>
Filters=""> <Folder
<F Name="Other Files"
N="Makefile" Filters="">
Type="Makefile"/> <F
</Folder> N="Makefile"
</Files> Type="Makefile"/>
</Folder>
</Files>
</Project> </Project>