...
 
Commits (4)
......@@ -12,7 +12,12 @@ SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
FILE(GLOB_RECURSE source_files src/*.cpp src/*.h src/*.inl)
ADD_EXECUTABLE(${PROJECT_NAME} ${source_files})
IF(WIN32)
# ADD_EXECUTABLE(${PROJECT_NAME} WIN32 ${source_files})
ADD_EXECUTABLE(${PROJECT_NAME} ${source_files})
ELSE(WIN32)
ADD_EXECUTABLE(${PROJECT_NAME} ${source_files})
ENDIF(WIN32)
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
......@@ -22,6 +27,9 @@ INCLUDE("FindOpenViBEModuleXML")
INCLUDE("FindOpenViBEModuleEBML")
INCLUDE("FindOpenViBEModuleFS")
INCLUDE("FindThirdPartyGTK")
INCLUDE("FindThirdPartyBoost")
INCLUDE("FindThirdPartyBoost_Thread")
INCLUDE("FindThirdPartyEigen")
# ---------------------------------
# Target macros
......
......@@ -5,6 +5,8 @@
#include <openvibe/ovITimeArithmetics.h>
#include <boost/thread.hpp>
#define OVD_GUI_File OpenViBE::Directories::getDataDir() + "/applications/designer/interface.ui"
using namespace OpenViBE;
......
......@@ -16,6 +16,14 @@
#include "ovdCInterfacedScenario.h"
#include "ovdCApplication.h"
#if defined(TARGET_OS_Windows) && defined(TEST_NO_CONSOLE)
// #include <Windows.h>
// msvcrt
// extern int __cdecl __getmainargs( int *argc, char ***argv, char ***envp,
// int expand_wildcards, int *new_mode );
#endif
using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;
......@@ -24,6 +32,10 @@ using namespace std;
map<uint32, ::GdkColor> g_vColors;
#if TARGET_HAS_ThirdPartyEIGEN
#include <Eigen/Core>
#endif
class CPluginObjectDescEnum
{
public:
......@@ -37,7 +49,7 @@ public:
{
}
virtual boolean enumeratePluginObjectDesc(void)
virtual OpenViBE::boolean enumeratePluginObjectDesc(void)
{
CIdentifier l_oIdentifier;
while((l_oIdentifier=m_rKernelContext.getPluginManager().getNextPluginObjectDescIdentifier(l_oIdentifier))!=OV_UndefinedIdentifier)
......@@ -47,7 +59,7 @@ public:
return true;
}
virtual boolean enumeratePluginObjectDesc(
virtual OpenViBE::boolean enumeratePluginObjectDesc(
const CIdentifier& rParentClassIdentifier)
{
CIdentifier l_oIdentifier;
......@@ -58,7 +70,7 @@ public:
return true;
}
virtual boolean callback(
virtual OpenViBE::boolean callback(
const IPluginObjectDesc& rPluginObjectDesc)=0;
protected:
......@@ -79,7 +91,7 @@ public:
{
}
virtual boolean callback(
virtual OpenViBE::boolean callback(
const IPluginObjectDesc& rPluginObjectDesc)
{
string l_sFullName=string(rPluginObjectDesc.getCategory())+"/"+string(rPluginObjectDesc.getName());
......@@ -115,7 +127,7 @@ public:
{
}
virtual boolean callback(
virtual OpenViBE::boolean callback(
const IPluginObjectDesc& rPluginObjectDesc)
{
// Outputs plugin info to console
......@@ -150,7 +162,7 @@ static void insertPluginObjectDesc_to_GtkTreeStore(const IKernelContext& rKernel
l_sStockItemName=l_pBoxAlgorithmDesc->getStockItemName();
}
boolean l_bShouldShow=true;
OpenViBE::boolean l_bShouldShow=true;
if (rKernelContext.getPluginManager().isPluginObjectFlaggedAsDeprecated(l_pPluginObjectDesc->getCreatedClass())
&& !rKernelContext.getConfigurationManager().expandAsBoolean("${Designer_ShowDeprecated}", false))
......@@ -160,7 +172,7 @@ static void insertPluginObjectDesc_to_GtkTreeStore(const IKernelContext& rKernel
/*
if (rKernelContext.getPluginManager().isPluginObjectFlaggedAsUnstable(l_pPluginObjectDesc->getCreatedClass())
&& !rKernelContext.getConfigurationManager().expandAsBoolean("${Designer_ShowUnstable}", false))
&& !rKernelContext.getConfigurationManager().expandAsOpenViBE::boolean("${Designer_ShowUnstable}", false))
{
l_bShouldShow=false;
}
......@@ -200,8 +212,8 @@ static void insertPluginObjectDesc_to_GtkTreeStore(const IKernelContext& rKernel
::GtkTreeIter* l_pGtkIterChild=&l_oGtkIter1;
for(it=l_vCategory.begin(); it!=l_vCategory.end(); it++)
{
boolean l_bFound=false;
boolean l_bValid=gtk_tree_model_iter_children(
OpenViBE::boolean l_bFound=false;
OpenViBE::boolean l_bValid=gtk_tree_model_iter_children(
GTK_TREE_MODEL(pTreeStore),
l_pGtkIterChild,
l_pGtkIterParent)?true:false;
......@@ -300,6 +312,7 @@ typedef struct _SConfiguration
} SConfiguration;
OpenViBE::boolean parse_arguments(int argc, char** argv, SConfiguration& rConfiguration)
/* About hide/show flags.
* no-gui => hides the designer main window, shows visualisation widgets.
* no-visualisation => shows the designer main window, hides display of visualisation widgets.
......@@ -311,7 +324,6 @@ typedef struct _SConfiguration
* If the designer main window is not visible, the flag no-check-color-depth can be activated (the color depth has been reported to cause trouble
* only in the designer main window).
*/
boolean parse_arguments(int argc, char** argv, SConfiguration& rConfiguration)
{
SConfiguration l_oConfiguration;
......@@ -432,7 +444,7 @@ boolean parse_arguments(int argc, char** argv, SConfiguration& rConfiguration)
int go(int argc, char ** argv)
{
boolean errorWhileLoadingScenario = false;
OpenViBE::boolean errorWhileLoadingScenario = false;
/*
{ 0, 0, 0, 0 },
{ 0, 16383, 16383, 16383 },
......@@ -459,7 +471,6 @@ int go(int argc, char ** argv)
cout << " --play filename : plays the opened scenario (see also --no-session-management)\n";
cout << " --play-fast filename : plays fast forward the opened scenario (see also --no-session-management)\n";
cout << " --random-seed uint : initialize random number generator with value, default=time(NULL)\n";
// l_rLogManager << LogLevel_Info << " --define : defines a variable in the configuration manager\n";
return -1;
}
......@@ -569,6 +580,14 @@ int go(int argc, char ** argv)
setlocale( LC_ALL, l_sLocale.toASCIIString() );
//initialise Gtk before 3D context
#if !GLIB_CHECK_VERSION(2,32,0)
// although deprecated in newer GTKs (no more needed after (at least) 2.24.13, deprecated in 2.32), we need to use this on Windows with the older GTK (2.22.1), or acquisition server will crash on startup
g_thread_init(NULL);
#endif
gdk_threads_init();
gdk_threads_enter();
if(!gtk_init_check(&argc, &argv))
{
l_rLogManager << LogLevel_Error << "Unable to initialize GTK. Possibly the display could not be opened. Exiting.\n";
......@@ -581,6 +600,7 @@ int go(int argc, char ** argv)
return -2;
}
// gtk_rc_parse(OpenViBE::Directories::getDataDir() + "/applications/designer/interface.gtkrc");
#ifdef TARGET_OS_Linux
......@@ -610,7 +630,7 @@ int go(int argc, char ** argv)
::CApplication app(*l_pKernelContext);
app.initialize(l_oConfiguration.getFlags());
// FIXME is it necessary to keep next line uncomment ?
//boolean l_bIsScreenValid=true;
//OpenViBE::boolean l_bIsScreenValid=true;
if(!l_oConfiguration.m_eNoCheckColorDepth)
{
if(GDK_IS_DRAWABLE(GTK_WIDGET(app.m_pMainWindow)->window))
......@@ -661,8 +681,6 @@ int go(int argc, char ** argv)
}
}
break;
// case CommandLineFlag_Define:
// break;
default:
break;
}
......@@ -695,6 +713,8 @@ int go(int argc, char ** argv)
}
}
gdk_threads_leave();
l_rLogManager << LogLevel_Info << "Application terminated, releasing allocated objects\n";
OpenViBEToolkit::uninitialize(*l_pKernelContext);
......@@ -713,8 +733,61 @@ int go(int argc, char ** argv)
return 0;
}
#if defined(TARGET_OS_Windows) && defined(TEST_NO_CONSOLE)
int __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int cmdShow)
{
int argc = -1;
char **argv = NULL;
char **env = NULL;
int start_info = 0;
__getmainargs(&argc, &argv, &env, 0, &start_info);
int l_iRet=-1;
try
{
l_iRet=go(argc, argv);
}
catch (...)
{
std::cout << "Caught an exception at the very top...\nLeaving application!\n";
}
return l_iRet;
}
#else
int main(int argc, char ** argv)
{
#if defined(TARGET_OS_Windows) && defined(TEST_NO_CONSOLE)
// FreeConsole();
#endif
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#if (EIGEN_WORLD_VERSION >= 3) && (EIGEN_MAJOR_VERSION >= 2)
Eigen::initParallel();
// Eigen::setNbThreads(4);
// std::cout << "Eigen: I'm using " << Eigen::nbThreads() << " threads\n";
#endif
#if DEBUG
#ifdef EIGEN_VECTORIZE
std::cout << "Eigen: Vectorization is compiled\n";
#else
std::cout << "Eigen: Vectorization is NOT compiled\n";
#ifdef EIGEN_DONT_VECTORIZE
std::cout << "Eigen: (DONT_VECTORIZE is on)\n";
#endif
#endif
#endif
#endif
int l_iRet=-1;
try
{
......@@ -726,3 +799,5 @@ int main(int argc, char ** argv)
}
return l_iRet;
}
#endif
\ No newline at end of file
......@@ -29,6 +29,8 @@ CAlgorithmManager::~CAlgorithmManager(void)
CIdentifier CAlgorithmManager::createAlgorithm(
const CIdentifier& rAlgorithmClassIdentifier)
{
boost::mutex::scoped_lock lock(m_oLock);
const IAlgorithmDesc* l_pAlgorithmDesc=NULL;
IAlgorithm* l_pAlgorithm=getKernelContext().getPluginManager().createAlgorithm(rAlgorithmClassIdentifier, &l_pAlgorithmDesc);
if(!l_pAlgorithm || !l_pAlgorithmDesc)
......@@ -49,6 +51,8 @@ CIdentifier CAlgorithmManager::createAlgorithm(
boolean CAlgorithmManager::releaseAlgorithm(
const CIdentifier& rAlgorithmIdentifier)
{
boost::mutex::scoped_lock lock(m_oLock);
map < CIdentifier, pair < CAlgorithm*, CAlgorithmProxy* > >::iterator itAlgorithm;
itAlgorithm=m_vAlgorithm.find(rAlgorithmIdentifier);
if(itAlgorithm==m_vAlgorithm.end())
......@@ -76,6 +80,8 @@ boolean CAlgorithmManager::releaseAlgorithm(
boolean CAlgorithmManager::releaseAlgorithm(
IAlgorithmProxy& rAlgorithm)
{
boost::mutex::scoped_lock lock(m_oLock);
map < CIdentifier, pair < CAlgorithm*, CAlgorithmProxy* > >::iterator itAlgorithm;
for(itAlgorithm=m_vAlgorithm.begin(); itAlgorithm!=m_vAlgorithm.end(); itAlgorithm++)
{
......@@ -105,6 +111,8 @@ boolean CAlgorithmManager::releaseAlgorithm(
IAlgorithmProxy& CAlgorithmManager::getAlgorithm(
const CIdentifier& rAlgorithmIdentifier)
{
boost::mutex::scoped_lock lock(m_oLock);
map < CIdentifier, pair < CAlgorithm*, CAlgorithmProxy* > >::const_iterator itAlgorithm;
itAlgorithm=m_vAlgorithm.find(rAlgorithmIdentifier);
if(itAlgorithm==m_vAlgorithm.end())
......@@ -117,6 +125,8 @@ IAlgorithmProxy& CAlgorithmManager::getAlgorithm(
CIdentifier CAlgorithmManager::getNextAlgorithmIdentifier(
const CIdentifier& rPreviousIdentifier) const
{
boost::mutex::scoped_lock lock(m_oLock);
map < CIdentifier, pair < CAlgorithm*, CAlgorithmProxy* > >::const_iterator itAlgorithm=m_vAlgorithm.begin();
if(rPreviousIdentifier==OV_UndefinedIdentifier)
......
......@@ -5,6 +5,9 @@
#include <map>
#include <boost/thread.hpp> // for mutex
#include <boost/thread/condition.hpp>
namespace OpenViBE
{
namespace Kernel
......@@ -39,6 +42,8 @@ namespace OpenViBE
protected:
std::map < OpenViBE::CIdentifier, std::pair < OpenViBE::Kernel::CAlgorithm*, OpenViBE::Kernel::CAlgorithmProxy* > > m_vAlgorithm;
mutable boost::mutex m_oLock; // Protects the array for threads
};
};
};
......
......@@ -178,12 +178,16 @@ CConfigurationManager::CConfigurationManager(const IKernelContext& rKernelContex
void CConfigurationManager::clear(void)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
m_vConfigurationToken.clear();
}
boolean CConfigurationManager::addConfigurationFromFile(
const CString& rFileNameWildCard)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
this->getLogManager() << LogLevel_Info << "Adding configuration file(s) [" << rFileNameWildCard << "]\n";
boolean l_bResult;
......@@ -201,6 +205,8 @@ CIdentifier CConfigurationManager::createConfigurationToken(
const CString& rConfigurationTokenName,
const CString& rConfigurationTokenValue)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(this->lookUpConfigurationTokenIdentifier(rConfigurationTokenName, false)!=OV_UndefinedIdentifier)
{
this->getLogManager() << LogLevel_Warning << "Configuration token name " << rConfigurationTokenName << " already exists\n";
......@@ -216,6 +222,8 @@ CIdentifier CConfigurationManager::createConfigurationToken(
boolean CConfigurationManager::releaseConfigurationToken(
const CIdentifier& rConfigurationTokenIdentifier)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::iterator itConfigurationToken=m_vConfigurationToken.find(rConfigurationTokenIdentifier);
if(itConfigurationToken==m_vConfigurationToken.end())
{
......@@ -229,6 +237,8 @@ boolean CConfigurationManager::releaseConfigurationToken(
CIdentifier CConfigurationManager::getNextConfigurationTokenIdentifier(
const CIdentifier& rPreviousConfigurationTokenIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::const_iterator itConfigurationToken;
if(rPreviousConfigurationTokenIdentifier==OV_UndefinedIdentifier)
......@@ -253,6 +263,8 @@ CIdentifier CConfigurationManager::getNextConfigurationTokenIdentifier(
CString CConfigurationManager::getConfigurationTokenName(
const CIdentifier& rConfigurationTokenIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::const_iterator itConfigurationToken=m_vConfigurationToken.find(rConfigurationTokenIdentifier);
if(itConfigurationToken!=m_vConfigurationToken.end())
{
......@@ -264,6 +276,8 @@ CString CConfigurationManager::getConfigurationTokenName(
CString CConfigurationManager::getConfigurationTokenValue(
const CIdentifier& rConfigurationTokenIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::const_iterator itConfigurationToken=m_vConfigurationToken.find(rConfigurationTokenIdentifier);
if(itConfigurationToken!=m_vConfigurationToken.end())
{
......@@ -278,6 +292,8 @@ boolean CConfigurationManager::setConfigurationTokenName(
const CIdentifier& rConfigurationTokenIdentifier,
const CString& rConfigurationTokenName)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(this->lookUpConfigurationTokenIdentifier(rConfigurationTokenName, false)!=OV_UndefinedIdentifier)
{
getLogManager() << LogLevel_Warning << "Configuration token " << rConfigurationTokenName << " already exists\n";
......@@ -299,6 +315,8 @@ boolean CConfigurationManager::setConfigurationTokenValue(
const CIdentifier& rConfigurationTokenIdentifier,
const CString& rConfigurationTokenValue)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::iterator itConfigurationToken=m_vConfigurationToken.find(rConfigurationTokenIdentifier);
if(itConfigurationToken==m_vConfigurationToken.end())
{
......@@ -314,6 +332,8 @@ boolean CConfigurationManager::addOrReplaceConfigurationToken(
const CString& rConfigurationTokenName,
const CString& rConfigurationTokenValue)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
const CIdentifier l_oOldIdentifier = this->lookUpConfigurationTokenIdentifier(rConfigurationTokenName, false);
if(l_oOldIdentifier == OV_UndefinedIdentifier)
{
......@@ -331,6 +351,8 @@ CIdentifier CConfigurationManager::lookUpConfigurationTokenIdentifier(
const CString& rConfigurationTokenName,
const boolean bRecursive) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::const_iterator itConfigurationToken=m_vConfigurationToken.begin();
while(itConfigurationToken!=m_vConfigurationToken.end())
{
......@@ -350,6 +372,8 @@ CIdentifier CConfigurationManager::lookUpConfigurationTokenIdentifier(
CString CConfigurationManager::lookUpConfigurationTokenValue(
const CString& rConfigurationTokenName) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, SConfigurationToken >::const_iterator itConfigurationToken=m_vConfigurationToken.begin();
while(itConfigurationToken!=m_vConfigurationToken.end())
{
......@@ -384,6 +408,8 @@ CString CConfigurationManager::expand(
CIdentifier CConfigurationManager::getUnusedIdentifier(void) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
uint64 l_ui64Identifier=(((uint64)rand())<<32)+((uint64)rand());
CIdentifier l_oResult;
std::map < CIdentifier, SConfigurationToken >::const_iterator i;
......
......@@ -6,6 +6,9 @@
#include <map>
#include <string>
#include <boost/thread.hpp> // for mutex
#include <boost/thread/condition.hpp>
namespace OpenViBE
{
namespace Kernel
......@@ -105,6 +108,9 @@ namespace OpenViBE
protected:
std::map < OpenViBE::CIdentifier, OpenViBE::Kernel::SConfigurationToken > m_vConfigurationToken;
mutable boost::recursive_mutex m_oLock; // Protects the array for threads.
};
};
};
......
......@@ -6,6 +6,8 @@
#include <vector>
#include <map>
#include <boost/thread.hpp>
namespace OpenViBE
{
namespace Kernel
......@@ -50,10 +52,15 @@ namespace OpenViBE
_IsDerivedFromClass_Final_(OpenViBE::Kernel::TKernelObject<OpenViBE::Kernel::ILogManager>, OVK_ClassId_Kernel_Log_LogManager);
boost::mutex m_oMutex;
protected:
template <class T> void logForEach(T tValue)
{
// @fixme we need to create a buffer per thread (caller) and then on EOL, lock();flush buffer();unlock()
boost::mutex::scoped_lock lock(m_oMutex);
if(m_eCurrentLogLevel!=LogLevel_None && this->isActive(m_eCurrentLogLevel))
{
std::vector<OpenViBE::Kernel::ILogListener*>::iterator i;
......
// @short Essentially has a buffer per calling thread and then on EOL, does lock();flush buffer();unlock()
//
// @long Operating philosophy: Maintains a log buffer per thread and flushes it to all the
// listeners after the thread writes an end of line. As the different listeners
// want to color things in different ways, we buffer the log write operations using
// a vector of boost::any, instead of buffering, for example, a raw log line itself.
// An additional complication of this is that we have to cast the data back runtime
// from boost::any to the types supported by the listeners.
//
// Known issues:
// - If the scheduler uses constantly new thread ids, this manager will slowly
// grow in memory size as the buffers are indexed by thread ids and the array
// is never truncated (the API doesn't currently allow logmanager to know about threads).
// - This log manager might not be the most efficient thing, as on each get
// of the buffer it needs to take a lock to the buffer array. However, writing a log line
// should rather be an exception than a rule in normal openvibe number crunching.
//
// @author J.T. Lindgren
//
#include "ovkCLogManagerMulticore.h"
// #include <iostream>
using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace std;
// Explicit type definitions for enums to carry in boost::any
typedef ELogLevel t_ELogLevel;
typedef ELogColor t_ELogColor;
CLogManagerMulticore::CLogManagerMulticore(const IKernelContext& rKernelContext)
:TKernelObject<ILogManager>(rKernelContext)
{
}
// @note this call is not thread safe
OpenViBE::boolean CLogManagerMulticore::isActive(ELogLevel eLogLevel)
{
map<ELogLevel, OpenViBE::boolean>::iterator itLogLevel=m_vActiveLevel.find(eLogLevel);
if(itLogLevel==m_vActiveLevel.end())
{
return true;
}
return itLogLevel->second;
}
// @note this call is not thread safe
OpenViBE::boolean CLogManagerMulticore::activate(ELogLevel eLogLevel, OpenViBE::boolean bActive)
{
m_vActiveLevel[eLogLevel]=bActive;
return true;
}
// @note this call is not thread safe
OpenViBE::boolean CLogManagerMulticore::activate(ELogLevel eStartLogLevel, ELogLevel eEndLogLevel, OpenViBE::boolean bActive)
{
for(int i=eStartLogLevel; i<=eEndLogLevel; i++)
{
m_vActiveLevel[ELogLevel(i)]=bActive;
}
return true;
}
// @note this call is not thread safe
OpenViBE::boolean CLogManagerMulticore::activate(OpenViBE::boolean bActive)
{
return activate(LogLevel_First, LogLevel_Last, bActive);
}
void CLogManagerMulticore::log(const time64 time64Value)
{
pushToBuffer(time64Value);
}
void CLogManagerMulticore::log(const uint64 ui64Value)
{
pushToBuffer(ui64Value);
}
void CLogManagerMulticore::log(const uint32 ui32Value)
{
pushToBuffer(ui32Value);
}
void CLogManagerMulticore::log(const uint16 ui16Value)
{
pushToBuffer(ui16Value);
}
void CLogManagerMulticore::log(const uint8 ui8Value)
{
pushToBuffer(ui8Value);
}
void CLogManagerMulticore::log(const int64 i64Value)
{
pushToBuffer(i64Value);
}
void CLogManagerMulticore::log(const int32 i32Value)
{
pushToBuffer(i32Value);
}
void CLogManagerMulticore::log(const int16 i16Value)
{
pushToBuffer(i16Value);
}
void CLogManagerMulticore::log(const int8 i8Value)
{
pushToBuffer(i8Value);
}
void CLogManagerMulticore::log(const float64 f64Value)
{
pushToBuffer(f64Value);
}
void CLogManagerMulticore::log(const float32 f32Value)
{
pushToBuffer(f32Value);
}
void CLogManagerMulticore::log(const OpenViBE::boolean bValue)
{
pushToBuffer(bValue);
}
void CLogManagerMulticore::log(const CIdentifier& rValue)
{
pushToBuffer(rValue);
}
void CLogManagerMulticore::log(const CString& rValue)
{
pushToBuffer(rValue);
std::string tmp(rValue.toASCIIString());
if(tmp.find("\n")!=string::npos)
{
flushBuffer();
}
}
void CLogManagerMulticore::log(const char* rValue)
{
std::string l_sCopy(rValue);
pushToBuffer(l_sCopy);
if(l_sCopy.find("\n")!=string::npos)
{
flushBuffer();
}
}
void CLogManagerMulticore::log(const ELogLevel eLogLevel)
{
LogBuffer& l_oBuffer = getBuffer();
l_oBuffer.m_eCurrentLogLevel = eLogLevel;
pushToBuffer(static_cast<t_ELogLevel>(eLogLevel));
}
void CLogManagerMulticore::log(const ELogColor eLogColor)
{
pushToBuffer(static_cast<t_ELogColor>(eLogColor));
}
OpenViBE::boolean CLogManagerMulticore::addListener(ILogListener* pListener)
{
if(pListener==NULL)
{
return false;
}
vector<ILogListener*>::iterator itLogListener=m_vListener.begin();
while(itLogListener!=m_vListener.end())
{
if((*itLogListener)==pListener)
{
return false;
}
itLogListener++;
}
m_vListener.push_back(pListener);
return true;
}
OpenViBE::boolean CLogManagerMulticore::removeListener(ILogListener* pListener)
{
vector<ILogListener*>::iterator itLogListener=m_vListener.begin();
while(itLogListener!=m_vListener.end())
{
if((*itLogListener)==pListener)
{
m_vListener.erase(itLogListener);
return true; // due to constraint in addListener(), pListener can be in the array only once, so we can return
}
itLogListener++;
}
return false;
}
CLogManagerMulticore::LogBuffer& CLogManagerMulticore::getBuffer()
{
const boost::thread::id l_oThreadId = boost::this_thread::get_id();
{
boost::mutex::scoped_lock lock(m_oBufferLock);
// get buffer structure for this thread, if not found, make a new one
if(m_vLogBuffer.find(l_oThreadId)==m_vLogBuffer.end())
{
m_vLogBuffer[l_oThreadId].m_vBuffer = std::vector<boost::any>();
m_vLogBuffer[l_oThreadId].m_eCurrentLogLevel = LogLevel_Info;
}
return m_vLogBuffer[l_oThreadId];
}
}
OpenViBE::boolean CLogManagerMulticore::flushBuffer()
{
LogBuffer& l_oBuffer = getBuffer();
{
// We need to hold the lock so we can spool the whole line to the listener without interference
boost::mutex::scoped_lock lock(m_oOutputLock);
std::vector<OpenViBE::Kernel::ILogListener*>::iterator i;
for(i=m_vListener.begin(); i!=m_vListener.end(); i++)
{
if((*i)->isActive(l_oBuffer.m_eCurrentLogLevel))
{
for(uint32 j=0;j<l_oBuffer.m_vBuffer.size();j++)
{
boost::any& l_oValue = l_oBuffer.m_vBuffer[j];
if(l_oValue.type()==typeid(t_ELogLevel))
{
(*i)->log(boost::any_cast<ELogLevel>(l_oValue));
}
else if(l_oValue.type()==typeid(t_ELogColor))
{
(*i)->log(boost::any_cast<ELogColor>(l_oValue));
}
else if(l_oValue.type()==typeid(time64))
{
(*i)->log(boost::any_cast<time64>(l_oValue));
}
else if(l_oValue.type()==typeid(CString))
{
(*i)->log(boost::any_cast<CString>(l_oValue));
}
else if(l_oValue.type()==typeid(std::string))
{
// handle separately from cstring since some listeners want to put a different color
const std::string tmp = boost::any_cast<std::string>(l_oValue);
const char *ptr = tmp.c_str();
(*i)->log(ptr);
}
else if(l_oValue.type()==typeid(CIdentifier))
{
(*i)->log(boost::any_cast<CIdentifier>(l_oValue));
}
else if(l_oValue.type()==typeid(float64))
{
(*i)->log(boost::any_cast<float64>(l_oValue));
}
else if(l_oValue.type()==typeid(float32))
{
(*i)->log(boost::any_cast<float32>(l_oValue));
}
else if(l_oValue.type()==typeid(uint64))
{
(*i)->log(boost::any_cast<uint64>(l_oValue));
}
else if(l_oValue.type()==typeid(uint32))
{
(*i)->log(boost::any_cast<uint32>(l_oValue));
}
else if(l_oValue.type()==typeid(uint16))
{
(*i)->log(boost::any_cast<uint16>(l_oValue));
}
else if(l_oValue.type()==typeid(uint8))
{
(*i)->log(boost::any_cast<uint8>(l_oValue));
}
else if(l_oValue.type()==typeid(int64))
{
(*i)->log(boost::any_cast<int64>(l_oValue));
}
else if(l_oValue.type()==typeid(int32))
{
(*i)->log(boost::any_cast<int32>(l_oValue));
}
else if(l_oValue.type()==typeid(int16))
{
(*i)->log(boost::any_cast<int16>(l_oValue));
}
else if(l_oValue.type()==typeid(int8))
{
(*i)->log(boost::any_cast<int8>(l_oValue));
}
else if(l_oValue.type()==typeid(OpenViBE::boolean))
{
(*i)->log(boost::any_cast<OpenViBE::boolean>(l_oValue));
}
else
{
(*i)->log(CString("Error: Unknown type ") + CString(l_oValue.type().name()) + CString("\n"));
}
}
}
}
}
l_oBuffer.m_vBuffer.clear();
return true;
}
#ifndef __OpenViBEKernel_Kernel_Log_CLogManagerMulticore_h__
#define __OpenViBEKernel_Kernel_Log_CLogManagerMulticore_h__
#include "../ovkTKernelObject.h"
#include <vector>
#include <map>
#include <boost/thread.hpp>
#include <boost/any.hpp>
namespace OpenViBE
{
namespace Kernel
{
class CLogManagerMulticore : public OpenViBE::Kernel::TKernelObject<OpenViBE::Kernel::ILogManager>
{
public:
CLogManagerMulticore(const OpenViBE::Kernel::IKernelContext& rKernelContext);
virtual OpenViBE::boolean isActive(OpenViBE::Kernel::ELogLevel eLogLevel);
virtual OpenViBE::boolean activate(OpenViBE::Kernel::ELogLevel eLogLevel, OpenViBE::boolean bActive);
virtual OpenViBE::boolean activate(OpenViBE::Kernel::ELogLevel eStartLogLevel, OpenViBE::Kernel::ELogLevel eEndLogLevel, OpenViBE::boolean bActive);
virtual OpenViBE::boolean activate(OpenViBE::boolean bActive);
virtual void log(const OpenViBE::time64 time64Value);
virtual void log(const OpenViBE::uint64 ui64Value);
virtual void log(const OpenViBE::uint32 ui32Value);
virtual void log(const OpenViBE::uint16 ui16Value);
virtual void log(const OpenViBE::uint8 ui8Value);
virtual void log(const OpenViBE::int64 i64Value);
virtual void log(const OpenViBE::int32 i32Value);
virtual void log(const OpenViBE::int16 i16Value);
virtual void log(const OpenViBE::int8 i8Value);
virtual void log(const OpenViBE::float64 f64Value);
virtual void log(const OpenViBE::float32 f32Value);
virtual void log(const OpenViBE::boolean bValue);
virtual void log(const OpenViBE::CIdentifier& rValue);
virtual void log(const OpenViBE::CString& rValue);
virtual void log(const char* pValue);
virtual void log(const OpenViBE::Kernel::ELogLevel eLogLevel);
virtual void log(const OpenViBE::Kernel::ELogColor eLogColor);
virtual OpenViBE::boolean addListener(OpenViBE::Kernel::ILogListener* pListener);
virtual OpenViBE::boolean removeListener(OpenViBE::Kernel::ILogListener* pListener);
_IsDerivedFromClass_Final_(OpenViBE::Kernel::TKernelObject<OpenViBE::Kernel::ILogManager>, OVK_ClassId_Kernel_Log_LogManager);
protected:
// Caches per-thread buffer & its loglevel
struct LogBuffer
{
std::vector<boost::any> m_vBuffer;
ELogLevel m_eCurrentLogLevel;
};
// Get the buffer of the current thread
LogBuffer& getBuffer();
// Flush the buffer of the current thread
OpenViBE::boolean flushBuffer();
// Insert a log item into the current threads buffer
template <class T> void pushToBuffer(const T oValue)
{
// note here we lose the ref on purpose on oValue since the caller may release the data before we flush
LogBuffer& l_oMyBuffer = getBuffer();
if(l_oMyBuffer.m_eCurrentLogLevel!=LogLevel_None && this->isActive(l_oMyBuffer.m_eCurrentLogLevel))
{
l_oMyBuffer.m_vBuffer.push_back(oValue);
}
}
protected:
boost::mutex m_oBufferLock; // Guards the LogBuffer map
boost::mutex m_oOutputLock; // Guards the calls to the listeners
std::map<boost::thread::id, LogBuffer> m_vLogBuffer;
std::vector<OpenViBE::Kernel::ILogListener*> m_vListener;
std::map<OpenViBE::Kernel::ELogLevel, OpenViBE::boolean> m_vActiveLevel;
};
};
};
#endif // __OpenViBEKernel_Kernel_Log_CLogManagerMulticore_h__
......@@ -7,7 +7,8 @@
#include "player/ovkCPlayerManager.h"
#include "plugins/ovkCPluginManager.h"
#include "scenario/ovkCScenarioManager.h"
#include "log/ovkCLogManager.h"
// #include "log/ovkCLogManager.h"
#include "log/ovkCLogManagerMulticore.h"
#include "log/ovkCLogListenerConsole.h"
#include "log/ovkCLogListenerFile.h"
#include "visualisation/ovkCVisualisationManager.h"
......@@ -147,7 +148,8 @@ boolean CKernelContext::initialize(void)
this->getLogManager() << LogLevel_Trace << "Creating log manager\n";
m_pLogManager=new CLogManager(m_rMasterKernelContext);
// m_pLogManager=new CLogManager(m_rMasterKernelContext);
m_pLogManager=new CLogManagerMulticore(m_rMasterKernelContext);
m_pLogManager->activate(true);
this->getLogManager() << LogLevel_Trace << "Creating and configuring console log listener\n";
......
#include "ovkCTypeManager.h"
#include "../ovk_tools.h"
#include <string>
......@@ -33,6 +35,8 @@ CTypeManager::CTypeManager(const IKernelContext& rKernelContext)
CIdentifier CTypeManager::getNextTypeIdentifier(
const CIdentifier& rPreviousIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
return getNextIdentifier< CString >(m_vName, rPreviousIdentifier);
}
......@@ -40,10 +44,13 @@ boolean CTypeManager::registerType(
const CIdentifier& rTypeIdentifier,
const CString& sTypeName)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(isRegistered(rTypeIdentifier))
{
return false;
}
m_vName[rTypeIdentifier]=sTypeName;
this->getLogManager() << LogLevel_Trace << "Registered type id " << rTypeIdentifier << " - " << sTypeName << "\n";
return true;
......@@ -54,6 +61,8 @@ boolean CTypeManager::registerStreamType(
const CString& sTypeName,
const CIdentifier& rParentTypeIdentifier)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(isRegistered(rTypeIdentifier))
{
return false;
......@@ -72,14 +81,19 @@ boolean CTypeManager::registerEnumerationType(
const CIdentifier& rTypeIdentifier,
const CString& sTypeName)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(isRegistered(rTypeIdentifier))
{
return false;
}
m_vName[rTypeIdentifier]=sTypeName;
m_vEnumeration[rTypeIdentifier];
this->getLogManager() << LogLevel_Trace << "Registered enumeration type id " << rTypeIdentifier << " - " << sTypeName << "\n";
return true;
}
boolean CTypeManager::registerEnumerationEntry(
......@@ -87,6 +101,8 @@ boolean CTypeManager::registerEnumerationEntry(
const CString& sEntryName,
const uint64 ui64EntryValue)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::iterator itEnumeration=m_vEnumeration.find(rTypeIdentifier);
if(itEnumeration==m_vEnumeration.end())
{
......@@ -105,6 +121,8 @@ boolean CTypeManager::registerBitMaskType(
const CIdentifier& rTypeIdentifier,
const CString& sTypeName)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(isRegistered(rTypeIdentifier))
{
return false;
......@@ -120,6 +138,8 @@ boolean CTypeManager::registerBitMaskEntry(
const CString& sEntryName,
const uint64 ui64EntryValue)
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......@@ -149,12 +169,16 @@ boolean CTypeManager::registerBitMaskEntry(
boolean CTypeManager::isRegistered(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
return m_vName.find(rTypeIdentifier)!=m_vName.end()?true:false;
}
boolean CTypeManager::isStream(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
return m_vStream.find(rTypeIdentifier)!=m_vStream.end()?true:false;
}
......@@ -162,6 +186,8 @@ boolean CTypeManager::isDerivedFromStream(
const CIdentifier& rTypeIdentifier,
const CIdentifier& rParentTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map < CIdentifier, CIdentifier >::const_iterator it=m_vStream.find(rTypeIdentifier);
std::map < CIdentifier, CIdentifier >::const_iterator itParent=m_vStream.find(rParentTypeIdentifier);
if(it==m_vStream.end()) return false;
......@@ -180,38 +206,50 @@ boolean CTypeManager::isDerivedFromStream(
boolean CTypeManager::isEnumeration(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
return m_vEnumeration.find(rTypeIdentifier)!=m_vEnumeration.end()?true:false;
}
boolean CTypeManager::isBitMask(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
return m_vBitMask.find(rTypeIdentifier)!=m_vBitMask.end()?true:false;
}
CString CTypeManager::getTypeName(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(!isRegistered(rTypeIdentifier))
{
return CString("");
}
return m_vName.find(rTypeIdentifier)->second;
}
CIdentifier CTypeManager::getStreamParentType(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
if(!isStream(rTypeIdentifier))
{
return OV_UndefinedIdentifier;
}
return m_vStream.find(rTypeIdentifier)->second;
}
uint64 CTypeManager::getEnumerationEntryCount(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itEnumeration=m_vEnumeration.find(rTypeIdentifier);
if(itEnumeration==m_vEnumeration.end())
{
......@@ -226,6 +264,8 @@ boolean CTypeManager::getEnumerationEntry(
CString& sEntryName,
uint64& rEntryValue) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itEnumeration=m_vEnumeration.find(rTypeIdentifier);
if(itEnumeration==m_vEnumeration.end())
{
......@@ -252,6 +292,8 @@ CString CTypeManager::getEnumerationEntryNameFromValue(
const CIdentifier& rTypeIdentifier,
const uint64 ui64EntryValue) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itEnumeration=m_vEnumeration.find(rTypeIdentifier);
if(itEnumeration==m_vEnumeration.end())
{
......@@ -269,6 +311,8 @@ uint64 CTypeManager::getEnumerationEntryValueFromName(
const CIdentifier& rTypeIdentifier,
const CString& rEntryName) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itEnumeration=m_vEnumeration.find(rTypeIdentifier);
std::map<uint64, CString>::const_iterator itEnumerationEntry;
if(itEnumeration==m_vEnumeration.end())
......@@ -314,6 +358,8 @@ uint64 CTypeManager::getEnumerationEntryValueFromName(
uint64 CTypeManager::getBitMaskEntryCount(
const CIdentifier& rTypeIdentifier) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......@@ -328,6 +374,8 @@ boolean CTypeManager::getBitMaskEntry(
CString& sEntryName,
uint64& rEntryValue) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......@@ -354,6 +402,8 @@ CString CTypeManager::getBitMaskEntryNameFromValue(
const CIdentifier& rTypeIdentifier,
const uint64 ui64EntryValue) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......@@ -371,6 +421,8 @@ uint64 CTypeManager::getBitMaskEntryValueFromName(
const CIdentifier& rTypeIdentifier,
const CString& rEntryName) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
std::map<uint64, CString>::const_iterator itBitMaskEntry;
if(itBitMask==m_vBitMask.end())
......@@ -417,6 +469,8 @@ CString CTypeManager::getBitMaskEntryCompositionNameFromValue(
const CIdentifier& rTypeIdentifier,
const uint64 ui64EntryCompositionValue) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......@@ -452,6 +506,8 @@ uint64 CTypeManager::getBitMaskEntryCompositionValueFromName(
const CIdentifier& rTypeIdentifier,
const CString& rEntryCompositionName) const
{
boost::recursive_mutex::scoped_lock lock(m_oLock);
std::map<CIdentifier, std::map<uint64, CString> >::const_iterator itBitMask=m_vBitMask.find(rTypeIdentifier);
if(itBitMask==m_vBitMask.end())
{
......
......@@ -5,6 +5,10 @@
#include <map>
#include <boost/thread.hpp> // for mutex
#include <boost/thread/condition.hpp>
#include <boost/thread/recursive_mutex.hpp>
namespace OpenViBE
{
namespace Kernel
......@@ -103,6 +107,8 @@ namespace OpenViBE
std::map<OpenViBE::CIdentifier, std::map<OpenViBE::uint64, OpenViBE::CString> > m_vEnumeration;
std::map<OpenViBE::CIdentifier, std::map<OpenViBE::uint64, OpenViBE::CString> > m_vBitMask;
std::map<OpenViBE::CIdentifier, OpenViBE::CIdentifier> m_vStream;
mutable boost::recursive_mutex m_oLock; // Protects the arrays for threads. Recursive as the functions touching the arrays call each other.
};
};
};
......
......@@ -38,9 +38,7 @@ public:
OpenViBE::boolean m_bIsParsingSettingOverride;
OpenViBE::Kernel::IConfigurationManager* m_pConfigurationManager;
#undef boolean
_IsDerivedFromClass_Final_(OpenViBE::IObjectVisitor, OV_UndefinedIdentifier);
#define boolean OpenViBE::boolean
};
#endif
\ No newline at end of file
......@@ -3,6 +3,7 @@
#include "../ovkTKernelObject.h"
#include "ovkCScheduler.h"
#include "ovkCSchedulerMulticore.h"
#include "../ovkCKernelContext.h"
......@@ -48,7 +49,9 @@ namespace OpenViBE
OpenViBE::Kernel::CKernelContextBridge m_oKernelContextBridge;
OpenViBE::Kernel::IConfigurationManager* m_pLocalConfigurationManager;
OpenViBE::Kernel::CScheduler m_oScheduler;
// For now, switch between these to change the schedulers
// OpenViBE::Kernel::CScheduler m_oScheduler;
OpenViBE::Kernel::CSchedulerMulticore m_oScheduler;
OpenViBE::uint64 m_ui64CurrentTimeToReach;
OpenViBE::uint64 m_ui64Lateness;
......
......@@ -44,7 +44,7 @@ namespace OpenViBE
virtual OpenViBE::uint64 getFrequency(void) const;
virtual OpenViBE::float64 getCPUUsage(void) const;
bool sendMessage(const IMessageWithData &msg, CIdentifier targetBox, uint32 inputIndex);
virtual OpenViBE::boolean sendMessage(const IMessageWithData &msg, CIdentifier targetBox, uint32 inputIndex);
_IsDerivedFromClass_Final_(OpenViBE::Kernel::TKernelObject < OpenViBE::Kernel::IKernelObject >, OVK_ClassId_Kernel_Player_Scheduler);
......
#include <openvibe/ovITimeArithmetics.h>
#include "ovkCSchedulerMulticore.h"
#include "ovkCSimulatedBox.h"
#include "ovkCPlayer.h"
#include "ovkCBoxSettingModifierVisitor.h"
#include <system/ovCTime.h>
#include <xml/IReader.h>
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <limits>
//___________________________________________________________________//
// //
using namespace std;
using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;
//___________________________________________________________________//
// //
static uint32 g_ui32NumThreads = 4;
boolean parallelExecutor::initialize(const uint32 nThreads)
{
// Basically jobContext is the stuff that the scheduler and parallel executor use to communicate the status of the jobs
m_oJobContext.m_bQuit = false;
m_oJobContext.m_ui32JobsPending = 0;
m_oJobContext.m_vJobList.clear();
for(uint32 i=0;i<nThreads;i++)
{
m_vWorkerThread.push_back(new CWorkerThread(m_oJobContext));
m_vThread.push_back(new boost::thread(boost::bind(&CWorkerThread::startWorkerThread, m_vWorkerThread[i])));
}
return true;
}
boolean parallelExecutor::uninitialize()
{
// Make sure all jobs have been completed
waitForAll();
// Tell the threads waiting in the cond its time to quit
{ // scope for lock
boost::unique_lock<boost::mutex> lock(m_oJobContext.m_oJobMutex);
m_oJobContext.m_bQuit = true;
}
m_oJobContext.m_oHaveWork.notify_all();
for(uint32 i=0;i<m_vThread.size();i++)
{
m_vThread[i]->join();
delete m_vThread[i];
delete m_vWorkerThread[i];
}
m_vThread.clear();
m_vWorkerThread.clear();
return true;
}
boolean parallelExecutor::push(const jobCall& someJob)
{
// @fixme to add better concurrency, push a list instead; lock();add list;unlock();notify_all();
{ // lock scope
boost::lock_guard<boost::mutex> lock(m_oJobContext.m_oJobMutex);
m_oJobContext.m_vJobList.push_back(someJob);
m_oJobContext.m_ui32JobsPending++;
}
m_oJobContext.m_oHaveWork.notify_one();
return true;
}
boolean parallelExecutor::pushList(const std::deque<jobCall>& vJobList)
{
{ // lock scope
boost::lock_guard<boost::mutex> lock(m_oJobContext.m_oJobMutex);
if(m_oJobContext.m_ui32JobsPending) {
std::cout << "Error, trying to push list with old jobs pending\n";
return false;
}
m_oJobContext.m_vJobList = vJobList;
m_oJobContext.m_ui32JobsPending = vJobList.size();
}
m_oJobContext.m_oHaveWork.notify_all();
return true;
}
boolean parallelExecutor::waitForAll()
{
{ // lock scope
boost::unique_lock<boost::mutex> lock(m_oJobContext.m_oJobMutex);
while(m_oJobContext.m_ui32JobsPending>0) {
m_oJobContext.m_oJobDone.wait(lock);
}
}
return true;
}
//___________________________________________________________________//
// //
boolean testFunction(void* data) {
for(uint32 i=0;i<10;i++) {
std::cout << "Fun: " << *(uint32*)(data) << "\n";
System::Time::sleep(*(uint32*)data);
}
return true;
}
CSchedulerMulticore::CSchedulerMulticore(const IKernelContext& rKernelContext, CPlayer& rPlayer)
: CScheduler(rKernelContext, rPlayer)
,m_rPlayer(rPlayer)
,m_oScenarioIdentifier(OV_UndefinedIdentifier)
,m_pScenario(NULL)
,m_ui64Steps(0)
,m_ui64Frequency(0)
,m_ui64CurrentTime(0)
,m_bIsInitialized(false)
{
int stuff[6] = {500,666,50,1000,300,100};
m_oExecutor.initialize(g_ui32NumThreads);
// m_oExecutor.push(boost::bind(CSchedulerMulticore::job, this));
/*
m_oExecutor.push(boost::bind(testFunction, &stuff[0]));
// test.push(jobInfo(boost::bind(&CSchedulerMulticore::job, this)));
// boost::bind(&CWorkerThread::startWorkerThread, m_vWorkerThread[i])));
*/
/*
parallelExecutor test;
test.initialize(3);
test.push(boost::bind(testFunction, &stuff[0]));
test.waitForAll();
test.push(boost::bind(testFunction, &stuff[1]));
test.push(boost::bind(testFunction, &stuff[2]));
test.push(boost::bind(testFunction, &stuff[3]));
test.push(boost::bind(testFunction, &stuff[4]));
test.push(boost::bind(testFunction, &stuff[2]));
test.waitForAll();
test.waitForAll();
test.uninitialize();
*/
}
CSchedulerMulticore::~CSchedulerMulticore(void)
{
m_oExecutor.uninitialize();
if(m_bIsInitialized)
{
this->uninitialize();
}
}
//___________________________________________________________________//
// //
boolean CSchedulerMulticore::setScenario(
const CIdentifier& rScenarioIdentifier)
{
this->getLogManager() << LogLevel_Trace << "Scheduler setScenario\n";
if(m_bIsInitialized)
{
this->getLogManager() << LogLevel_Warning << "Trying to configure an intialized scheduler !\n";
return false;
}
m_oScenarioIdentifier=rScenarioIdentifier;
m_pScenario=NULL;
return true;
}
boolean CSchedulerMulticore::setFrequency(
const uint64 ui64Frequency)
{
this->getLogManager() << LogLevel_Trace << "Scheduler setFrequency\n";
if(m_bIsInitialized)
{
this->getLogManager() << LogLevel_Warning << "Trying to configure an intialized scheduler !\n";
return false;
}
m_ui64Frequency=ui64Frequency;
return true;
}
//___________________________________________________________________//
// //
SchedulerInitializationCode CSchedulerMulticore::initialize(void)
{
this->getLogManager() << LogLevel_Trace << "Scheduler initialize\n";
if(m_bIsInitialized)
{
this->getLogManager() << LogLevel_Warning << "Trying to initialize an intialized scheduler !\n";
return SchedulerInitialization_Failed;
}
m_pScenario=&getScenarioManager().getScenario(m_oScenarioIdentifier);
if(!m_pScenario)
{
this->getLogManager() << LogLevel_ImportantWarning << "Scenario " << m_oScenarioIdentifier << " does not exist !\n";
return SchedulerInitialization_Failed;
}
CBoxSettingModifierVisitor l_oBoxSettingModifierVisitor(&getKernelContext().getConfigurationManager());
if(!m_pScenario->acceptVisitor(l_oBoxSettingModifierVisitor))
{
this->getLogManager() << LogLevel_Error << "Scenario " << m_oScenarioIdentifier << " setting modification with acceptVisitor() failed\n";
return SchedulerInitialization_Failed;
}
CIdentifier l_oBoxIdentifier;
while((l_oBoxIdentifier=m_pScenario->getNextBoxIdentifier(l_oBoxIdentifier))!=OV_UndefinedIdentifier)
{
const IBox* l_pBox=m_pScenario->getBoxDetails(l_oBoxIdentifier);
int l_iPriority = 0;
if(l_pBox->hasAttribute(OV_AttributeId_Box_Priority))
{
// This is mostly retained for debugging use. The value can be entered to .xml by hand but there is no GUI to change this (on purpose)
::sscanf(l_pBox->getAttributeValue(OV_AttributeId_Box_Priority).toASCIIString(), "%i", &l_iPriority);
}
else
{
// Decide the priority based on the location of the box in the GUI. Priority decreases in top->bottom, left->right order.
int l_iYPosition = 0;
::sscanf(l_pBox->getAttributeValue(OV_AttributeId_Box_YCenterPosition).toASCIIString(), "%i", &l_iYPosition);
int l_iXPosition = 0;
::sscanf(l_pBox->getAttributeValue(OV_AttributeId_Box_XCenterPosition).toASCIIString(), "%i", &l_iXPosition);
this->getLogManager() << LogLevel_Debug << " Inserting box " << l_pBox->getName() << " with coords (x=" << l_iXPosition << ",y=" << l_iYPosition << ")\n";
const int32 l_iMaxInt16 = std::numeric_limits<int16>::max(); // Signed max
l_iYPosition = std::max(std::min(l_iYPosition,l_iMaxInt16),0); // y = Truncate to 0:int16
l_iXPosition = std::max(std::min(l_iXPosition,l_iMaxInt16),0); // x = Truncate to 0:int16
l_iPriority = -( (l_iYPosition << 15) + l_iXPosition); // compose pri32=[int16,int16] = [y,x]
this->getLogManager() << LogLevel_Debug << " -> coord-based box priority is " << l_iPriority << "\n";
}
CSimulatedBox* l_pSimulatedBox=new CSimulatedBox(getKernelContext(), *this);
l_pSimulatedBox->setScenarioIdentifier(m_oScenarioIdentifier);
l_pSimulatedBox->setBoxIdentifier(l_oBoxIdentifier);
m_vSimulatedBox[std::make_pair(-l_iPriority, l_oBoxIdentifier)]=l_pSimulatedBox;
m_vSimulatedBoxChrono[l_oBoxIdentifier].reset(static_cast<uint32>(m_ui64Frequency));
m_vSimulatedBoxInputMutex[l_oBoxIdentifier] = new boost::mutex();
}
boolean l_bBoxInitialization = true;
for(map < pair < int32, CIdentifier >, CSimulatedBox* >::iterator itSimulatedBox=m_vSimulatedBox.begin(); itSimulatedBox!=m_vSimulatedBox.end(); itSimulatedBox++)
{
const IBox* l_pBox=m_pScenario->getBoxDetails(itSimulatedBox->first.second);
this->getLogManager() << LogLevel_Trace << "Scheduled box : id = " << itSimulatedBox->first.second << " priority = " << -itSimulatedBox->first.first << " name = " << l_pBox->getName() << "\n";
if(itSimulatedBox->second ) // we initialize regardless of mute so that we can bring the box back during the run (in theory...)
{
if(!itSimulatedBox->second->initialize())
{
l_bBoxInitialization = false;
}
}
}
m_ui64Steps=0;
m_ui64CurrentTime=0;
m_bIsInitialized=true;
m_oBenchmarkChrono.reset((System::uint32)m_ui64Frequency);
if(l_bBoxInitialization)
{
return SchedulerInitialization_Success;
}
return SchedulerInitialization_BoxInitializationFailed;
}
boolean CSchedulerMulticore::uninitialize(void)
{
this->getLogManager() << LogLevel_Trace << "Scheduler uninitialize\n";
if(!m_bIsInitialized)
{
this->getLogManager() << LogLevel_Warning << "Trying to uninitialize an uninitialized player !\n";
return false;
}
for(map < pair < int32, CIdentifier >, CSimulatedBox* >::iterator itSimulatedBox=m_vSimulatedBox.begin(); itSimulatedBox!=m_vSimulatedBox.end(); itSimulatedBox++)
{
if(itSimulatedBox->second)
{
itSimulatedBox->second->uninitialize();
}
}