int* waiting_workers;
int worker_count;
+ int iterations;
int max_iterations;
int worker_id;
} worker_arg;
}
void* iterator(void* _arg)
+{
+ worker_arg* warg = (worker_arg*)_arg;
+ RD_Opts opts = warg->opts;
+ int start_x = warg->start_x;
+ int start_y = warg->start_y;
+ int w = warg->width;//(warg->width + start_x >= GRID_X) ? GRID_X-1 - start_x: warg->width;
+ int h = warg->height;//(warg->height + start_y >= GRID_Y) ? GRID_Y-1 - start_y : warg->height;
+
+ for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++)
+ {
+ printf("worker %d: work unit %d/%d\n", warg->worker_id, warg->iterations, warg->max_iterations);
+ for (int x = start_x; x < w + start_x; x++)
+ {
+ for (int y = start_y; y < h + start_y; y++)
+ {
+ FVec2 each = grid[x][y];
+ grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
+ grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
+ }
+ }
+
+#if 1
+ // Last one done should wake up the boss thread
+ int last_worker = 0;
+ pthread_mutex_lock(warg->mutex);
+ if (++*warg->waiting_workers == warg->worker_count)
+ {
+ last_worker = 1;
+ }
+ pthread_mutex_unlock(warg->mutex);
+
+ if (last_worker == 0)
+ {
+ pthread_cond_wait(warg->worker_cond, &warg->worker_mutex);
+ }
+ else
+ {
+ grid_temp = grid;
+ grid = grid_prime;
+ grid_prime = grid_temp;
+
+ // segfault somewhere in here lmao
+ if (1 && (warg->iterations % 100 == 0))
+ {
+ char buffer[GRID_X][GRID_Y];
+ for (int x = 0; x < GRID_X; x++)
+ {
+ for (int y = 0; y < GRID_Y; y++)
+ {
+ buffer[x][y] = (uint8_t)(255.0f * grid[x][y].a);
+ }
+ }
+ char name[64] = {0};
+ sprintf(name, "img/%s/%d.png", opts.name, warg->iterations);
+ stbi_write_png(name, GRID_X, GRID_Y, 1, buffer, GRID_X * sizeof(uint8_t));
+ }
+ printf("worker-boss %d: completing report\n", warg->worker_id);
+
+ *warg->waiting_workers = 0;
+ pthread_cond_broadcast(warg->worker_cond);
+ }
+#endif
+ }
+
+ printf("worker %d: exiting\n", warg->worker_id);
+ return _arg;
+}
+
+void* iterator_old(void* _arg)
{
worker_arg* warg = (worker_arg*)_arg;
RD_Opts opts = warg->opts;
}
}
+ // Last one done should wake up the boss thread
+ pthread_mutex_lock(warg->mutex);
++*warg->waiting_workers;
- printf("worker %d: waking up boss\n", warg->worker_id);
- pthread_cond_signal(warg->boss_cond);
+ if (*warg->waiting_workers == warg->worker_count)
+ {
+ printf("worker %d: waking up boss\n", warg->worker_id);
+ pthread_cond_signal(warg->boss_cond);
+ }
+ pthread_mutex_unlock(warg->mutex);
pthread_cond_wait(warg->worker_cond, &warg->worker_mutex);
{
wargs[t] = warg;
wargs[t].worker_id = t;
- wargs[t].width = (GRID_X/warg.worker_count);
+ wargs[t].width = (GRID_X/warg.worker_count) + ((t == warg.worker_count-1) ? 0 : 4);
wargs[t].start_x = (wargs[t].width * t);
pthread_mutex_init(&wargs[t].worker_mutex, NULL);
printf("worker %d x_span %d, %d\n", t, wargs[t].start_x, wargs[t].width);
int max_iterations = (GRID_X / 128.0f) * opts.max_iterations;
max_iterations = warg.max_iterations;
+ /*
for (int iterations = 0; iterations < max_iterations; iterations++)
{
printf("boss: waiting on workers\n");
+ pthread_mutex_lock(warg.mutex);
while (*warg.waiting_workers < warg.worker_count)
{
pthread_cond_wait(warg.boss_cond, warg.mutex);
}
+ pthread_mutex_unlock(warg.mutex);
grid_temp = grid;
grid = grid_prime;
}
}
- *warg.waiting_workers = 0;
- pthread_cond_broadcast(warg.worker_cond);
+ }
+ */
+
+ int should_quit = 0;
+ while(!should_quit)
+ {
+ pthread_mutex_lock(warg.mutex);
+ if (wargs[0].iterations == wargs[0].max_iterations-1)
+ should_quit = 1;
+ pthread_mutex_unlock(warg.mutex);
}
printf("boss: exiting loop\n");