+typedef struct{
+ int start;
+ int end;
+} thread_args;
+
+void* parallel_search_cols(void *arg){
+ thread_args *args = (thread_args *)arg;
+ for(int r = 0; r < m_rows; r++){
+ for(int c = args->start; c < args->end; c++){
+ if(matrix[r][c] > hv){
+ hv = matrix[r][c];
+ }
+ }
+ }
+ free(args);
+ return NULL;
+}
+
+// Function to dynamically create threads and divide columns
+void run_parallel_search(int num_threads) {
+ // 1. Dynamically allocate arrays for threads and their arguments
+ pthread_t *threads = malloc(num_threads * sizeof(pthread_t));
+ thread_args *args = malloc(num_threads * sizeof(thread_args));
+
+ if (threads == NULL || args == NULL) {
+ perror("Failed to allocate memory for threads");
+ exit(1);
+ }
+
+ // 2. Calculate the base number of columns each thread will process
+ int chunk_size = m_cols / num_threads;
+
+ // 3. Create the threads in a loop
+ for (int i = 0; i < num_threads; i++) {
+ args[i].start = i * chunk_size;
+
+ // If it is the last thread, let it process all remaining columns
+ if (i == num_threads - 1) {
+ args[i].end = m_cols;
+ } else {
+ args[i].end = (i + 1) * chunk_size;
+ }
+
+ // Pass the address of the specific struct for this thread
+ if (pthread_create(&threads[i], NULL, ¶llel_search_cols, &args[i]) != 0) {
+ perror("Failed to create thread");
+ exit(1);
+ }
+ }
+
+ // 4. Wait for all threads to finish
+ for (int i = 0; i < num_threads; i++) {
+ pthread_join(threads[i], NULL);
+ }
+
+ // 5. Clean up the dynamically allocated arrays
+ free(threads);
+ // Note: Do not free(args) here IF your thread function (parallel_search_cols)
+ // is already calling free(arg) internally!
+ // Since your original thread function calls free(args), calling it here
+ // would cause a "double free" crash.
+ // However, since we allocated it as one big array, it is better to remove
+ // free(args) from your thread function and do it here:
+ free(args);
+}