Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once;
- #include <atomic>
- #include <stack>
- #include <thread>
- #include <Windows.h>
- #define THREADPOOL_THREADMAX (16)
- #define FORCEINLINE __inline
- typedef uint64_t SyncVal;
- typedef uint64_t ThreadId;
- class ThreadPool;
- class ThreadRegulator//muss auf dem stack jedes threads des threadpools liegen
- {
- public:
- ThreadId GetId()
- {
- return Id;
- }
- friend ThreadPool;
- private:
- ThreadRegulator(SyncVal NewLocalSync, ThreadId NewId) :
- LocalSync(NewLocalSync),
- Id(NewId)
- {}
- SyncVal LocalSync;
- const ThreadId Id;
- };
- class ThreadPool
- {
- public:
- template<typename T>
- void Start(T Function, const size_t NewTotalThreadCount) //threads starten
- {
- if (TotalThreadCount > 0) return;//läuft schon, fehler abbrechen
- TotalThreadCount = NewTotalThreadCount;
- ThreadRegulatorRequestCount = 0;
- for (int i = 0; i < TotalThreadCount; ++i)
- {
- size_t ThreadRegulatorRequestCountOld = ThreadRegulatorRequestCount;
- Thread[i] = std::thread(Function);
- while (ThreadRegulatorRequestCountOld == ThreadRegulatorRequestCount)
- std::this_thread::sleep_for(std::chrono::microseconds(0));
- }
- }
- ThreadRegulator GetThreadRegulator() //jeder thread muss eine Regulator auf seinem Stack haben, den kann er hier anfordern
- {
- return ThreadRegulator(GlobalSync, ThreadRegulatorRequestCount.fetch_add(1));
- }
- void Join()//threads beehnden
- {
- for (int i = 0; i < TotalThreadCount; ++i)
- Thread[i].join();
- TotalThreadCount = 0;
- }
- size_t FORCEINLINE Sync(ThreadRegulator& Marker)//synchonisation
- {
- ++Marker.LocalSync; //eigenen marker verschieben
- Lock(); //locken
- const size_t ThisNumber = ++FinishedThredCount;
- if (ThisNumber + 1 == TotalThreadCount) //falls es der vorletzte ist
- {
- SuspendFinished();
- Unlock();
- WaitForGlobalSync(Marker);
- }
- else if (ThisNumber == TotalThreadCount) //falls es der letzte ist
- {
- DoGlobalSync();
- ResumeAll();
- Unlock();
- }
- else// falls es irgendeiner ist
- {
- SuspendFinished();
- FinishedThreadsStack.push(Marker.Id);//selber bereit machen zu schlafen
- Unlock();
- WaitForGlobalSync(Marker);
- }
- return ThisNumber;
- }
- private:
- void FORCEINLINE ResumeAll()
- {
- while (!SleepingThreadsStack.empty())
- {
- const ThreadId ToAwake = SleepingThreadsStack.top();
- SleepingThreadsStack.pop();
- ResumeThread(Thread[ToAwake].native_handle());
- }
- }
- void FORCEINLINE SuspendFinished()
- {
- while (!FinishedThreadsStack.empty())//andere schlafen legen
- {
- const ThreadId ToSleep = FinishedThreadsStack.top();
- SuspendThread(Thread[ToSleep].native_handle());
- SleepingThreadsStack.push(ToSleep);
- FinishedThreadsStack.pop();
- }
- }
- void FORCEINLINE Lock()
- {
- while (LockValue.exchange(true))
- std::this_thread::sleep_for(std::chrono::microseconds(0));
- }
- void FORCEINLINE Unlock()
- {
- LockValue = false;
- }
- void FORCEINLINE WaitForGlobalSync(ThreadRegulator& Marker)
- {
- while (Marker.LocalSync > GlobalSync)
- std::this_thread::sleep_for(std::chrono::microseconds(0));
- }
- void FORCEINLINE DoGlobalSync()
- {
- FinishedThredCount = 0;
- ++GlobalSync;
- }
- size_t TotalThreadCount = 0; //threadanzahl in dem threadpool
- std::thread Thread[THREADPOOL_THREADMAX];
- size_t FinishedThredCount = 0;
- SyncVal GlobalSync = 0;
- std::atomic<size_t> ThreadRegulatorRequestCount = 0;
- std::atomic<bool> LockValue = false;
- std::stack<ThreadId> FinishedThreadsStack;
- std::stack<ThreadId> SleepingThreadsStack;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement