Skip to content

Commit

Permalink
making the threads replazable, rather than fix c++ thread.
Browse files Browse the repository at this point in the history
thsi can allow for new to be use with libraries than do no support  c++ native threads
  • Loading branch information
JulioJerez committed Oct 27, 2024
1 parent 898c88e commit 31fcc2f
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 40 deletions.
6 changes: 4 additions & 2 deletions newton-4.00/sdk/dCollision/ndScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ ndVector ndScene::m_angularContactError2(D_CONTACT_ANGULAR_ERROR * D_CONTACT_ANG
ndVector ndScene::m_linearContactError2(D_CONTACT_TRANSLATION_ERROR * D_CONTACT_TRANSLATION_ERROR);

ndScene::ndScene()
:ndThreadPool("newtonWorker")
:ndClassAlloc()
,ndThreadPool("newtonWorker")
,m_bodyList()
,m_particleSetList()
,m_contactArray()
Expand Down Expand Up @@ -77,7 +78,8 @@ ndScene::ndScene()
}

ndScene::ndScene(const ndScene& src)
:ndThreadPool("newtonWorker")
:ndClassAlloc()
,ndThreadPool("newtonWorker")
,m_bodyList(src.m_bodyList)
,m_particleSetList()
,m_contactArray(src.m_contactArray)
Expand Down
2 changes: 1 addition & 1 deletion newton-4.00/sdk/dCollision/ndScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ndSceneTreeNotiFy : public ndClassAlloc
} D_GCC_NEWTON_ALIGN_32;

D_MSV_NEWTON_ALIGN_32
class ndScene : public ndThreadPool
class ndScene : public ndClassAlloc, public ndThreadPool
{
protected:
class ndContactPairs
Expand Down
3 changes: 0 additions & 3 deletions newton-4.00/sdk/dCollision/ndShapeCompound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ void ndShapeCompound::ndTreeArray::AddNode(ndNodeBase* const node, ndInt32 index
{
ndTreeArray::ndNode* const myNode = Insert(node, index);
node->m_myNode = myNode;
//node->m_shapeInstance->m_parent____ = parent;
node->m_shapeInstance->m_subCollisionHandle = myNode;
}

Expand All @@ -260,7 +259,6 @@ ndShapeCompound::ndShapeCompound()
,m_boxMinRadius(ndFloat32(0.0f))
,m_boxMaxRadius(ndFloat32(0.0f))
,m_root(nullptr)
//,m_ownerInstance(nullptr)
,m_idIndex(0)
{
}
Expand All @@ -272,7 +270,6 @@ ndShapeCompound::ndShapeCompound(const ndShapeCompound& source)
,m_boxMinRadius(ndFloat32(0.0f))
,m_boxMaxRadius(ndFloat32(0.0f))
,m_root(nullptr)
//,m_ownerInstance(m_ownerInstance)
,m_idIndex(0)
{
ndTreeArray::Iterator iter(source.m_array);
Expand Down
21 changes: 17 additions & 4 deletions newton-4.00/sdk/dCore/ndThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,26 @@
#pragma warning( disable : 4355)
#endif

ndThread::ndThread()
ndThreadInterface::ndThreadInterface()
:ndClassAlloc()
,ndThreadName()
,ndSemaphore()
{
}

ndThreadInterface::~ndThreadInterface()
{
}


ndThread::ndThread()
:ndThreadInterface()
#ifndef D_USE_THREAD_EMULATION
,ndAtomic<bool>(true)
,std::condition_variable()
,std::thread(&ndThread::ThreadFunctionCallback, this)
#endif
{
strcpy (m_name, "newtonWorker");
strcpy (m_name.m_name, "newtonWorker");
#ifndef D_USE_THREAD_EMULATION
store(false);
#endif
Expand All @@ -57,7 +66,7 @@ ndThread::~ndThread()

void ndThread::SetName(const char* const name)
{
strncpy(m_name, name, sizeof(m_name) - 1);
strncpy(m_name.m_name, name, sizeof(m_name) - 1);
#if defined(_MSC_VER) && !defined (D_USE_THREAD_EMULATION)
// a hideous way to set the thread name, bu this is how Microsoft does it
const DWORD MS_VC_EXCEPTION = 0x406D1388;
Expand Down Expand Up @@ -103,6 +112,10 @@ void ndThread::Signal()
#endif
}

void ndThread::Release()
{
}

void ndThread::ThreadFunctionCallback()
{
#ifndef D_USE_THREAD_EMULATION
Expand Down
34 changes: 23 additions & 11 deletions newton-4.00/sdk/dCore/ndThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,25 @@ class ndThreadName
char m_name[32];
};

class ndThreadInterface: public ndClassAlloc, public ndSemaphore
{
public:
D_CORE_API ndThreadInterface();
D_CORE_API virtual ~ndThreadInterface();

virtual void Signal() = 0;
virtual void Finish() = 0;
virtual void Release() = 0;
virtual void ThreadFunction() = 0;
virtual void ThreadFunctionCallback() = 0;
virtual void SetName(const char* const name) = 0;

ndThreadName m_name;
};

/// Base class for for all multi thread functionality.
class ndThread
:public ndClassAlloc
,public ndThreadName
,public ndSemaphore
:public ndThreadInterface
#ifndef D_USE_THREAD_EMULATION
,public ndAtomic<bool>
,public std::condition_variable
Expand All @@ -58,27 +72,25 @@ class ndThread

/// Set thread name.
/// Useful for when debugging or profiler and application.
D_CORE_API void SetName(const char* const name);
D_CORE_API virtual void SetName(const char* const name) override;

/// Set the thread, to execute one call to and go back to a wait state
D_CORE_API void Signal();
D_CORE_API virtual void Signal() override;

/// Force the thread loop to terminate.
/// This function must be call explicitly when the application
/// wants to terminate the thread because the destructor does not do it.
D_CORE_API void Finish();
D_CORE_API virtual void Finish() override;

/// Thread function to execute in a perpetual loop until the thread is terminated.
/// Each time the thread owner calls function Signal, the loop execute one call to
/// this function and upon return, the thread goes back to wait for another signal
/// or to exit the loop.
virtual void ThreadFunction() = 0;
//virtual virtual void ThreadFunction() = 0;

protected:
virtual void Release(){}

private:
void ThreadFunctionCallback();
D_CORE_API virtual void Release() override;
D_CORE_API virtual void ThreadFunctionCallback() override;
};

#endif
68 changes: 55 additions & 13 deletions newton-4.00/sdk/dCore/ndThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@
#include "ndThreadPool.h"
#include "ndThreadSyncUtils.h"

class ndThreadPool::ndMainThread: public ndThread
{
public:
ndMainThread(ndThreadPool* const owner)
:ndThread()
,m_owner(owner)
{
}

void ThreadFunction() override
{
m_owner->ThreadFunction();
}

virtual void Release()
{
m_owner->Release();
}

ndThreadPool* const m_owner;
};

ndThreadPool::ndWorker::ndWorker()
:ndThread()
,m_owner(nullptr)
Expand Down Expand Up @@ -112,19 +134,21 @@ void ndThreadPool::ndWorker::ThreadFunction()

ndThreadPool::ndThreadPool(const char* const baseName)
:ndSyncMutex()
,ndThread()
,m_main(nullptr)
,m_workers(nullptr)
,m_count(0)
{
char name[256];
m_main = new ndMainThread(this);
strncpy(m_baseName, baseName, sizeof (m_baseName));
snprintf(name, sizeof (name), "%s_%d", m_baseName, 0);
SetName(name);
m_main->SetName(name);
}

ndThreadPool::~ndThreadPool()
{
SetThreadCount(0);
delete m_main;
}

ndInt32 ndThreadPool::GetMaxThreads()
Expand All @@ -147,21 +171,29 @@ void ndThreadPool::SetThreadCount(ndInt32 count)
{
if (m_workers)
{
//m_count = 0;
//delete[] m_workers;
//m_workers = nullptr;
for (ndInt32 i = m_count - 1; i >= 0; --i)
{
m_workers[i] = ndSharedPtr<ndWorker>(nullptr);
}
m_count = 0;
delete[] m_workers;
m_workers = nullptr;
}
if (count)
{
m_count = count;
m_workers = new ndWorker[size_t(count)];
//m_workers = new ndWorker[size_t(count)];
m_workers = new ndSharedPtr<ndWorker>[size_t(count)];
for (ndInt32 i = 0; i < count; ++i)
{
char name[256];
m_workers[i].m_owner = this;
m_workers[i].m_threadIndex = i;
m_workers[i] = ndSharedPtr<ndWorker>(new ndWorker);
m_workers[i]->m_owner = this;
m_workers[i]->m_threadIndex = i;
snprintf(name, sizeof(name), "%s_%d", m_baseName, i + 1);
m_workers[i].SetName(name);
m_workers[i]->SetName(name);
}
}
}
Expand All @@ -173,7 +205,7 @@ void ndThreadPool::Begin()
D_TRACKTIME();
for (ndInt32 i = 0; i < m_count; ++i)
{
m_workers[i].Signal();
m_workers[i]->Signal();
}

auto BeginJobs = ndMakeObject::ndFunction([this](ndInt32, ndInt32)
Expand All @@ -188,9 +220,9 @@ void ndThreadPool::End()
#ifndef D_USE_THREAD_EMULATION
for (ndInt32 i = 0; i < m_count; ++i)
{
m_workers[i].ExecuteTask(nullptr);
m_workers[i]->ExecuteTask(nullptr);
#if !defined(D_USE_SYNC_SEMAPHORE)
m_workers[i].m_begin = 0;
m_workers[i]->m_begin = 0;
#endif
}

Expand All @@ -200,7 +232,7 @@ void ndThreadPool::End()
ndUnsigned8 looping = 0;
for (ndInt32 i = 0; i < m_count; ++i)
{
looping = ndUnsigned8(looping | m_workers[i].m_stillLooping);
looping = ndUnsigned8(looping | m_workers[i]->m_stillLooping);
}
stillLooping = ndUnsigned8(stillLooping & looping);
if (m_count)
Expand All @@ -216,10 +248,20 @@ void ndThreadPool::Release()
ndSyncMutex::Release();
}

void ndThreadPool::Finish()
{
m_main->Finish();
}

void ndThreadPool::Signal()
{
m_main->Signal();
}

void ndThreadPool::TickOne()
{
ndSyncMutex::Tick();
ndSemaphore::Signal();
m_main->ndSemaphore::Signal();
#ifdef D_USE_THREAD_EMULATION
ThreadFunction();
#endif
Expand All @@ -234,7 +276,7 @@ void ndThreadPool::WaitForWorkers()
ndUnsigned8 inProgess = 0;
for (ndInt32 i = 0; i < m_count; ++i)
{
inProgess = ndUnsigned8(inProgess | (m_workers[i].IsTaskInProgress()));
inProgess = ndUnsigned8(inProgess | (m_workers[i]->IsTaskInProgress()));
}
jobsInProgress = ndUnsigned8 (jobsInProgress & inProgess);
if (jobsInProgress)
Expand Down
25 changes: 19 additions & 6 deletions newton-4.00/sdk/dCore/ndThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#include "ndSyncMutex.h"
#include "ndSemaphore.h"
#include "ndClassAlloc.h"
#include "ndThreadSyncUtils.h"
#include "ndContainersAlloc.h"
#include "ndSharedPtr.h"

//#define D_USE_SYNC_SEMAPHORE

Expand Down Expand Up @@ -63,16 +66,20 @@ class ndTask
virtual void Execute() const = 0;
};

class ndThreadPool: public ndSyncMutex, public ndThread
D_MSV_NEWTON_ALIGN_32
//class ndThreadPool: public ndSyncMutex, public ndThread
class ndThreadPool: public ndSyncMutex
{
class ndMainThread;

class ndWorker: public ndThread
{
public:
D_CORE_API ndWorker();
D_CORE_API virtual ~ndWorker();

D_CORE_API ndUnsigned8 IsTaskInProgress() const;
D_CORE_API void ExecuteTask(ndTask* const task);
D_CORE_API virtual ndUnsigned8 IsTaskInProgress() const;
D_CORE_API virtual void ExecuteTask(ndTask* const task);

private:
virtual void ThreadFunction();
Expand Down Expand Up @@ -102,6 +109,10 @@ class ndThreadPool: public ndSyncMutex, public ndThread
D_CORE_API void TickOne();
D_CORE_API void Begin();
D_CORE_API void End();
D_CORE_API void Signal();
D_CORE_API void Finish();

virtual void ThreadFunction() = 0;

template <typename Function>
void ParallelExecute(const Function& ndFunction);
Expand All @@ -110,10 +121,11 @@ class ndThreadPool: public ndSyncMutex, public ndThread
D_CORE_API virtual void Release();
D_CORE_API virtual void WaitForWorkers();

ndWorker* m_workers;
ndThreadInterface* m_main;
ndSharedPtr<ndWorker>* m_workers;
ndInt32 m_count;
char m_baseName[32];
};
}D_GCC_NEWTON_ALIGN_32;

inline ndInt32 ndThreadPool::GetThreadCount() const
{
Expand Down Expand Up @@ -206,7 +218,8 @@ void ndThreadPool::ParallelExecute(const Function& callback)
for (ndInt32 i = 0; i < m_count; ++i)
{
ndTaskImplement<Function>* const job = &jobsArray[i + 1];
m_workers[i].ExecuteTask(job);
//m_workers[i].ExecuteTask(job);
m_workers[i]->ExecuteTask(job);
}

ndTaskImplement<Function>* const job = &jobsArray[0];
Expand Down

0 comments on commit 31fcc2f

Please sign in to comment.