@@ 14,10 14,61 @@
extern int points[WINDOW_WIDTH * WINDOW_HEIGHT];
+#include <getopt.h>
+
+int parse_arguments(int argc, char** argv, int* num_threads, int* max_iter) {
+ int opt;
+ int threads = 1;
+ int max_iterations = 100;
+
+ static struct option long_options[] = {{"threads", required_argument, 0, 't'},
+ {"iteration", required_argument, 0, 'i'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}};
+
+ while ((opt = getopt_long(argc, argv, "t:i:h", long_options, NULL)) != -1) {
+ switch (opt) {
+ case 't':
+ threads = atoi(optarg);
+ if (threads <= 0) {
+ fprintf(stderr, "Error: threads must be a positive integer\n");
+ return -1;
+ }
+ break;
+ case 'i':
+ max_iterations = atoi(optarg);
+ if (max_iterations <= 0) {
+ fprintf(stderr, "Error: max iterations must be a positive integer\n");
+ return -1;
+ }
+ break;
+ case 'h':
+ printf("Usage: %s [options]\n", argv[0]);
+ printf(" --threads N, -t N Number of threads to use (default: 1)\n");
+ printf(
+ " --iteration N, -i N Maximum iterations for Mandelbrot (default: 100)\n");
+ printf(" --help, -h Show this help message\n");
+ return -1;
+ default:
+ fprintf(stderr, "Use --help for usage information\n");
+ return -1;
+ }
+ }
+ *num_threads = threads;
+ *max_iter = max_iterations;
+ return 0;
+}
+
state_t* init() {
state_t* state = malloc(sizeof(state_t));
+ if (!state) {
+ fprintf(stderr, "malloc failed\n");
+ return NULL;
+ }
+
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
+ free(state);
return NULL;
}
SDL_Window* window =
@@ 73,10 124,7 @@ void* calculate_points_thread(void* arg) {
return NULL;
}
-void calculate_points_pthread(position_t* pos) {
- int max_iter = 100;
- int num_threads = 4;
-
+void calculate_points_pthread(position_t* pos, int num_threads, int max_iteration) {
pthread_t threads[num_threads];
thread_data_t thread_data[num_threads];
@@ 87,7 135,7 @@ void calculate_points_pthread(position_t* pos) {
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;
+ thread_data[t].max_iter = max_iteration;
if (t == num_threads - 1) {
thread_data[t].end_row += remaining_rows;
@@ 101,12 149,25 @@ void calculate_points_pthread(position_t* pos) {
}
}
-int main(void) {
+int main(int argc, char** argv) {
+ int num_threads;
+ int max_iteration;
+
+ int parse_result = parse_arguments(argc, argv, &num_threads, &max_iteration);
+ if (parse_result == -1) {
+ return 1;
+ }
+
state_t* state = init();
if (state == NULL) {
return -1;
}
+ state->num_threads = num_threads;
+ state->max_iteration = max_iteration;
+
+ printf("Using %d threads with %d max iterations\n", state->num_threads, state->max_iteration);
+
SDL_Event e;
bool running = true;
SDL_ShowWindow(state->window);
@@ 156,7 217,6 @@ int main(void) {
is_dragging = true;
drag_start_x = (float)e.button.x;
drag_start_y = (float)e.button.y;
- // store current view
drag_start_x_min = position.x_min;
drag_start_x_max = position.x_max;
drag_start_y_min = position.y_min;
@@ 186,7 246,6 @@ int main(void) {
double view_width = drag_start_x_max - drag_start_x_min;
double view_height = drag_start_y_max - drag_start_y_min;
- // Pan: shift the view opposite to mouse movement
double x_shift = dx * view_width / (WINDOW_WIDTH - 1);
double y_shift = dy * view_height / (WINDOW_HEIGHT - 1);
@@ 206,8 265,7 @@ int main(void) {
}
}
if (pos_updated) {
- // calculate_points(&position);
- calculate_points_pthread(&position);
+ calculate_points_pthread(&position, state->num_threads, state->max_iteration);
pos_updated = false;
}
draw_points(state->surface);