#include "operatingsystem.h" #include "c4d_memory.h" #include "c4d_thread.h" void XThreadMain(void* data) { ((C4DThread*)data)->Main(); } Bool XThreadTest(void* data) { return ((C4DThread*)data)->TestDBreak(); } static const Char* XThreadName(void* data) { return ((C4DThread*)data)->GetThreadName(); } C4DThread::C4DThread(void) { weak = false; bt = C4DOS.Bt->Alloc(XThreadMain, XThreadTest, this, XThreadName); } C4DThread::~C4DThread(void) { if (!weak) C4DOS.Bt->Free(bt); } Bool C4DThread::Start(THREADMODE mode, THREADPRIORITY priority) { if (!bt) return false; return C4DOS.Bt->Start(bt, mode, priority, nullptr); } void C4DThread::End(Bool wait) { if (bt) C4DOS.Bt->End(bt, wait); } void C4DThread::Wait(Bool checkevents) { if (bt) C4DOS.Bt->Wait(bt, checkevents); } GeSignal* GeSignal::Alloc(void) { return C4DOS.Bt->SIGAlloc(); } void GeSignal::Free(GeSignal*& sm) { C4DOS.Bt->SIGFree(sm); } Semaphore* Semaphore::Alloc(void) { return C4DOS.Bt->SMAlloc(); } void Semaphore::Free(Semaphore*& sm) { C4DOS.Bt->SMFree(sm); } MPThreadPool::MPThreadPool(void) { mp = nullptr; mpcount = 0; } MPThreadPool::~MPThreadPool(void) { if (!mp) return; C4DOS.Bt->MPEnd(mp); C4DOS.Bt->MPFree(mp); mp = nullptr; } Bool MPThreadPool::Init(const C4DThread& parent, Int32 count, C4DThread** thread) { return Init(parent.Get(), count, thread); } Bool MPThreadPool::Init(BaseThread* parent, Int32 count, C4DThread** thread) { if (mp) { C4DOS.Bt->MPFree(mp); mp = nullptr; mpcount = 0; } mpcount = count; mp = C4DOS.Bt->MPAlloc(parent, count, XThreadMain, XThreadTest, (void**)thread, XThreadName); Int32 i; for (i = 0; i < count; i++) { if (!thread[i]->weak) { thread[i]->weak = true; C4DOS.Bt->Free(thread[i]->bt); } thread[i]->bt = C4DOS.Bt->MPGetThread(mp, i); } return mp != nullptr; } Bool MPThreadPool::Start(THREADPRIORITY worker_priority) { BaseThread* bt = nullptr; Int32 i; for (i = 0; i < mpcount; i++) { bt = C4DOS.Bt->MPGetThread(mp, i); if (!bt || !C4DOS.Bt->Start(bt, THREADMODE_ASYNC, worker_priority, nullptr)) { C4DOS.Bt->MPEnd(mp); return false; } } return true; } C4DThread* MPThreadPool::WaitForNextFree(void) { return (C4DThread*)C4DOS.Bt->MPWaitForNextFree(mp); } void MPThreadPool::Wait(void) { C4DOS.Bt->MPWait(mp); } void MPThreadPool::End(void) { C4DOS.Bt->MPEnd(mp); }