DEVELOPMENT ENVIRONMENT

~alex/mandelbrot-set-gen

4e07116103e2fa09dd451a1399129cbfa457440c — Alejandro Laguna a month ago 5ce56c3
feat: multithreading using pthread
2 files changed, 56 insertions(+), 5 deletions(-)

M Makefile
M src/main.c
M Makefile => Makefile +1 -1
@@ 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)

M src/main.c => src/main.c +55 -4
@@ 7,7 7,7 @@
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_video.h>
#include <math.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>


@@ 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);