Advertisement
Guest User

Untitled

a guest
May 16th, 2014
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.48 KB | None | 0 0
  1. #pragma once;
  2.  
  3. #include <atomic>
  4. #include <stack>
  5. #include <thread>
  6. #include <Windows.h>
  7.  
  8. #define THREADPOOL_THREADMAX (16)
  9. #define FORCEINLINE __inline
  10.  
  11. typedef uint64_t SyncVal;
  12. typedef uint64_t ThreadId;
  13.  
  14. class ThreadPool;
  15.  
  16. class ThreadRegulator//muss auf dem stack jedes threads des threadpools liegen
  17. {
  18. public:
  19.     ThreadId GetId()
  20.     {
  21.         return Id;
  22.     }
  23.     friend ThreadPool;
  24. private:
  25.     ThreadRegulator(SyncVal NewLocalSync, ThreadId NewId) :
  26.         LocalSync(NewLocalSync),
  27.         Id(NewId)
  28.     {}
  29.  
  30.     SyncVal LocalSync;
  31.     const ThreadId Id;
  32. };
  33.  
  34. class ThreadPool
  35. {
  36. public:
  37.     template<typename T>
  38.     void Start(T Function, const size_t NewTotalThreadCount) //threads starten
  39.     {
  40.         if (TotalThreadCount > 0) return;//läuft schon, fehler abbrechen
  41.  
  42.         TotalThreadCount = NewTotalThreadCount;
  43.         ThreadRegulatorRequestCount = 0;
  44.  
  45.         for (int i = 0; i < TotalThreadCount; ++i)
  46.         {
  47.             size_t ThreadRegulatorRequestCountOld = ThreadRegulatorRequestCount;
  48.             Thread[i] = std::thread(Function);
  49.             while (ThreadRegulatorRequestCountOld == ThreadRegulatorRequestCount)
  50.                 std::this_thread::sleep_for(std::chrono::microseconds(0));
  51.         }
  52.     }
  53.     ThreadRegulator GetThreadRegulator() //jeder thread muss eine Regulator auf seinem Stack haben, den kann er hier anfordern
  54.     {
  55.         return ThreadRegulator(GlobalSync, ThreadRegulatorRequestCount.fetch_add(1));
  56.     }
  57.     void Join()//threads beehnden
  58.     {
  59.         for (int i = 0; i < TotalThreadCount; ++i)
  60.             Thread[i].join();
  61.         TotalThreadCount = 0;
  62.     }
  63.     size_t FORCEINLINE Sync(ThreadRegulator& Marker)//synchonisation
  64.     {
  65.         ++Marker.LocalSync; //eigenen marker verschieben
  66.  
  67.         Lock(); //locken
  68.         const size_t ThisNumber = ++FinishedThredCount;
  69.  
  70.         if (ThisNumber + 1 == TotalThreadCount) //falls es der vorletzte ist
  71.         {
  72.             SuspendFinished();
  73.  
  74.             Unlock();
  75.             WaitForGlobalSync(Marker);
  76.         }
  77.         else if (ThisNumber == TotalThreadCount) //falls es der letzte ist
  78.         {
  79.             DoGlobalSync();
  80.             ResumeAll();
  81.  
  82.             Unlock();
  83.         }
  84.         else// falls es irgendeiner ist
  85.         {
  86.             SuspendFinished();
  87.             FinishedThreadsStack.push(Marker.Id);//selber bereit machen zu schlafen
  88.  
  89.             Unlock();
  90.             WaitForGlobalSync(Marker);
  91.         }
  92.  
  93.         return ThisNumber;
  94.     }
  95. private:
  96.     void FORCEINLINE ResumeAll()
  97.     {
  98.         while (!SleepingThreadsStack.empty())
  99.         {
  100.             const ThreadId ToAwake = SleepingThreadsStack.top();
  101.             SleepingThreadsStack.pop();
  102.             ResumeThread(Thread[ToAwake].native_handle());
  103.         }
  104.     }
  105.     void FORCEINLINE SuspendFinished()
  106.     {
  107.         while (!FinishedThreadsStack.empty())//andere schlafen legen
  108.         {
  109.             const ThreadId ToSleep = FinishedThreadsStack.top();
  110.             SuspendThread(Thread[ToSleep].native_handle());
  111.  
  112.             SleepingThreadsStack.push(ToSleep);
  113.             FinishedThreadsStack.pop();
  114.         }
  115.     }
  116.     void FORCEINLINE Lock()
  117.     {
  118.         while (LockValue.exchange(true))
  119.             std::this_thread::sleep_for(std::chrono::microseconds(0));
  120.     }
  121.     void FORCEINLINE Unlock()
  122.     {
  123.         LockValue = false;
  124.     }
  125.     void FORCEINLINE WaitForGlobalSync(ThreadRegulator& Marker)
  126.     {
  127.         while (Marker.LocalSync > GlobalSync)
  128.             std::this_thread::sleep_for(std::chrono::microseconds(0));
  129.     }
  130.     void FORCEINLINE DoGlobalSync()
  131.     {
  132.         FinishedThredCount = 0;
  133.         ++GlobalSync;
  134.     }
  135.  
  136.     size_t TotalThreadCount = 0; //threadanzahl in dem threadpool
  137.  
  138.     std::thread Thread[THREADPOOL_THREADMAX];
  139.  
  140.     size_t FinishedThredCount = 0;
  141.     SyncVal GlobalSync = 0;
  142.  
  143.     std::atomic<size_t> ThreadRegulatorRequestCount = 0;
  144.  
  145.     std::atomic<bool> LockValue = false;
  146.     std::stack<ThreadId> FinishedThreadsStack;
  147.     std::stack<ThreadId> SleepingThreadsStack;
  148. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement