From 4e07116103e2fa09dd451a1399129cbfa457440c Mon Sep 17 00:00:00 2001 From: Alejandro Laguna Date: Thu, 30 Jul 2026 10:38:58 +0200 Subject: [PATCH] feat: multithreading using pthread --- Makefile | 2 +- src/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index debcc6bbf23f5a4288d91f6bb3142fbb2218c002..d06c2f05055ee8faec77678be522e21b82308dcf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -Wall -Wextra -Werror -g3 -I include/ -LIBFLAGS = -lm -lSDL3 +LIBFLAGS = -lm -lSDL3 -pthread SRC = src/main.c src/draw.c src/math.c OBJ = $(SRC:.c=.o) diff --git a/src/main.c b/src/main.c index 1b68d61e92b94f56ce73cbf8ca6997302e802562..1538a19f158c49febeb99b8eaa9f4f3497739267 100644 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ extern int points[WINDOW_WIDTH * WINDOW_HEIGHT]; state_t* init() { - state_t *state = malloc(sizeof(state_t)); + state_t* state = malloc(sizeof(state_t)); if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError()); return NULL; @@ -51,8 +51,58 @@ state_t* init() { return state; } +typedef struct { + position_t* pos; + int start_row; + int end_row; + int max_iter; +} thread_data_t; + +void* calculate_points_thread(void* arg) { + thread_data_t* data = (thread_data_t*)arg; + position_t* pos = data->pos; + int max_iter = data->max_iter; + + for (int py = data->start_row; py < data->end_row; py++) { + for (int px = 0; px < WINDOW_WIDTH; px++) { + double cr = pos->x_min + (pos->x_max - pos->x_min) * px / (WINDOW_WIDTH - 1); + double ci = pos->y_min + (pos->y_max - pos->y_min) * py / (WINDOW_HEIGHT - 1); + points[py * WINDOW_WIDTH + px] = mandelbrot_iterations(cr, ci, max_iter); + } + } + return NULL; +} + +void calculate_points_pthread(position_t* pos) { + int max_iter = 100; + int num_threads = 4; + + pthread_t threads[num_threads]; + thread_data_t thread_data[num_threads]; + + int rows_per_thread = WINDOW_HEIGHT / num_threads; + int remaining_rows = WINDOW_HEIGHT % num_threads; + + for (int t = 0; t < num_threads; t++) { + thread_data[t].pos = pos; + thread_data[t].start_row = t * rows_per_thread; + thread_data[t].end_row = (t + 1) * rows_per_thread; + thread_data[t].max_iter = max_iter; + + if (t == num_threads - 1) { + thread_data[t].end_row += remaining_rows; + } + + pthread_create(&threads[t], NULL, calculate_points_thread, &thread_data[t]); + } + + for (int t = 0; t < num_threads; t++) { + pthread_join(threads[t], NULL); + } +} + int main(void) { - state_t *state = init(); + state_t* state = init(); if (state == NULL) { return -1; } @@ -156,7 +206,8 @@ int main(void) { } } if (pos_updated) { - calculate_points(&position); + // calculate_points(&position); + calculate_points_pthread(&position); pos_updated = false; } draw_points(state->surface);