summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-08-27 22:06:44 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-08-27 22:06:44 +0100
commit65bb0e0f66a2218b59c9537436f1f75166994651 (patch)
tree23099f4e3e791554352154a66f56dc893c24f221
parent2d11304ab4726d3904344d908c93c84a76391707 (diff)
downloadabelian-sandpile-65bb0e0f66a2218b59c9537436f1f75166994651.tar.gz
abelian-sandpile-65bb0e0f66a2218b59c9537436f1f75166994651.tar.bz2
abelian-sandpile-65bb0e0f66a2218b59c9537436f1f75166994651.zip
(main)+kill threads when avalanche has completed
After the so-called "avalanche", where the fractal has finished forming as there are no more candidates for toppling, we no longer need the threads to be working. As an intensive operation, it makes no sense to continue processing when we are sure there is no further dynamic behaviour possible. Using a tick based solution, every DELTA ticks we check if the avalanche is completed. If so, we clean up all the threads AND ensure that we no longer need to be checking for avalanches.
-rw-r--r--main.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/main.c b/main.c
index dd8a1ac..65a6954 100644
--- a/main.c
+++ b/main.c
@@ -56,9 +56,19 @@ void *compute_thread(void *input)
return NULL;
}
-int main(void)
+bool completed_avalanche(state_t *state)
{
- state_t state = {NULL, 512, 512, 0, true, pow(2, 20)};
+ for (size_t i = 0; i < state->dwidth; ++i)
+ for (size_t j = 0; j < state->dwidth; ++j)
+ if (state->data[(i * state->dwidth) + j] >= 4)
+ return false;
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ // Setup "default" state
+ state_t state = {NULL, 512, 512, 0, true, pow(2, 16)};
state.data = calloc(state.dwidth * state.dwidth, sizeof(*state.data));
state.multiplier = state.window_len / state.dwidth;
state.data[(state.dwidth * state.dwidth / 2) + (state.dwidth / 2)] =
@@ -85,7 +95,9 @@ int main(void)
InitWindow(state.window_len, state.window_len, "Abelian sand pile");
SetTargetFPS(60);
- while (!WindowShouldClose())
+ const int DELTA = 100;
+ bool done = false;
+ for (uint64_t ticks = 0, prev_ticks = 0; !WindowShouldClose(); ++ticks)
{
if (IsKeyPressed(KEY_UP) || IsKeyDown(KEY_UP))
{
@@ -108,6 +120,21 @@ int main(void)
camera.zoom = zoom;
}
+ if (ticks - prev_ticks > DELTA && !done)
+ {
+ printf("Checking if avalanche is complete!\n");
+ if (completed_avalanche(&state))
+ {
+ state.thread_alive = false;
+ pthread_join(thread_a, NULL);
+ pthread_join(thread_b, NULL);
+ pthread_join(thread_c, NULL);
+ pthread_join(thread_d, NULL);
+ done = true;
+ }
+ prev_ticks = ticks;
+ }
+
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
{
Vector2 delta = Vector2Scale(GetMouseDelta(), -1.0f / camera.zoom);