feat: improved task counting thread safety
This commit is contained in:
parent
df31dea9c7
commit
32a9fc24e5
|
|
@ -17,7 +17,7 @@
|
|||
#define likely(cond_) (cond_)
|
||||
#endif
|
||||
|
||||
#define SIM_MULTITHREADING 0
|
||||
#define SIM_MULTITHREADING 1
|
||||
|
||||
namespace simulation {
|
||||
bool drawDebugInfo{ true };
|
||||
|
|
@ -35,6 +35,7 @@ static std::vector<std::shared_ptr<ThreadWorkload>> underpopulated{};
|
|||
static std::vector<std::shared_ptr<ThreadWorkload>> born{};
|
||||
static uint64_t generationStartTime{ 0 };
|
||||
static unsigned tasks{ 0 }; std::mutex tasksMutex{};
|
||||
static std::condition_variable tasksChanged{};
|
||||
|
||||
CellIterator::CellIterator(Cell begin, Cell end)
|
||||
: state{ begin } , begin{ begin }, end{ end } {}
|
||||
|
|
@ -77,14 +78,28 @@ static size_t CountNeighbors(Cell const &cell) {
|
|||
return count;
|
||||
}
|
||||
|
||||
static void BlockUntilTasksDone() {
|
||||
std::unique_lock lock{ tasksMutex };
|
||||
while (tasks > 0) {
|
||||
tasksChanged.wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void TaskBegin() {
|
||||
std::scoped_lock lock{ tasksMutex };
|
||||
tasks++;
|
||||
}
|
||||
|
||||
static void TaskComplete() {
|
||||
std::scoped_lock lock{ tasksMutex };
|
||||
if (--tasks == 0) {
|
||||
SDL_Log("Generation Complete %lfs", (double)(SDL_GetTicksNS() - generationStartTime) * 0.0000000001);
|
||||
}
|
||||
tasksChanged.notify_all();
|
||||
}
|
||||
|
||||
static void FindOverpopulated(std::shared_ptr<ThreadWorkload> wl) {
|
||||
TaskBegin();
|
||||
std::scoped_lock lock{ wl->mtx };
|
||||
wl->changes.clear();
|
||||
|
||||
|
|
@ -102,6 +117,7 @@ static void FindOverpopulated(std::shared_ptr<ThreadWorkload> wl) {
|
|||
}
|
||||
|
||||
static void FindUnderpopulated(std::shared_ptr<ThreadWorkload> wl) {
|
||||
TaskBegin();
|
||||
std::scoped_lock lock{ wl->mtx };
|
||||
wl->changes.clear();
|
||||
|
||||
|
|
@ -119,6 +135,7 @@ static void FindUnderpopulated(std::shared_ptr<ThreadWorkload> wl) {
|
|||
}
|
||||
|
||||
static void FindBorn(std::shared_ptr<ThreadWorkload> wl) {
|
||||
TaskBegin();
|
||||
std::scoped_lock lock{ wl->mtx };
|
||||
wl->changes.clear();
|
||||
|
||||
|
|
@ -139,6 +156,7 @@ static void FindBorn(std::shared_ptr<ThreadWorkload> wl) {
|
|||
static void PopulateChanges() {
|
||||
static bool first_run{ true };
|
||||
#if SIM_MULTITHREADING
|
||||
BlockUntilTasksDone();
|
||||
constexpr size_t split{ 4 };
|
||||
if (first_run) {
|
||||
first_run = false;
|
||||
|
|
@ -148,8 +166,6 @@ static void PopulateChanges() {
|
|||
}
|
||||
|
||||
SDL_Log("Multithreading ON");
|
||||
{ std::scoped_lock lock{ tasksMutex };
|
||||
tasks = 3 * split; }
|
||||
generationStartTime = SDL_GetTicksNS();
|
||||
size_t const seg_length{ living.size() / split };
|
||||
for (size_t i{ 0 }; i < split; ++i) {
|
||||
|
|
@ -196,6 +212,7 @@ static void PopulateChanges() {
|
|||
}
|
||||
|
||||
void InitializeRandom(size_t livingChance, int64_t fillArea) {
|
||||
BlockUntilTasksDone();
|
||||
living.clear();
|
||||
|
||||
Cell itr{ 0, 0 };
|
||||
|
|
@ -213,6 +230,7 @@ void InitializeRandom(size_t livingChance, int64_t fillArea) {
|
|||
}
|
||||
|
||||
void Step() {
|
||||
BlockUntilTasksDone();
|
||||
for (std::shared_ptr<ThreadWorkload> wl : underpopulated) {
|
||||
if (wl == nullptr) continue;
|
||||
std::scoped_lock l{ wl->mtx };
|
||||
|
|
@ -258,6 +276,7 @@ void Draw(SDL_Renderer *renderer, double cellSizePercent) {
|
|||
if (!drawDebugInfo) {
|
||||
return;
|
||||
}
|
||||
BlockUntilTasksDone();
|
||||
for (std::shared_ptr<ThreadWorkload> wl : overpopulated) {
|
||||
std::scoped_lock l{ wl->mtx };
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
|
||||
|
|
|
|||
Loading…
Reference in a new issue