diff --git a/lab4/src/find_min_max.c b/lab4/src/find_min_max.c new file mode 100755 index 000000000..f3be42e06 --- /dev/null +++ b/lab4/src/find_min_max.c @@ -0,0 +1,18 @@ +#include "find_min_max.h" + +#include <limits.h> + +struct MinMax GetMinMax(int *array, unsigned int begin, unsigned int end) { + struct MinMax min_max; + min_max.min = INT_MAX; + min_max.max = INT_MIN; + + int i; + for (i = begin; i <=end; i++){ + if (min_max.min > array[i]) + min_max.min = array[i]; + if(min_max.max < array[i]) + min_max.max = array[i]; + } + return min_max; +} diff --git a/lab4/src/find_min_max.h b/lab4/src/find_min_max.h new file mode 100755 index 000000000..07892028c --- /dev/null +++ b/lab4/src/find_min_max.h @@ -0,0 +1,8 @@ +#ifndef FIND_MIN_MAX_H +#define FIND_MIN_MAX_H + +#include "utils.h" + +struct MinMax GetMinMax(int *array, unsigned int begin, unsigned int end); + +#endif diff --git a/lab4/src/parallel_min_max.c b/lab4/src/parallel_min_max.c new file mode 100755 index 000000000..1fb59904f --- /dev/null +++ b/lab4/src/parallel_min_max.c @@ -0,0 +1,230 @@ +#include <ctype.h> +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <getopt.h> + +#include <signal.h> + +#include "find_min_max.h" +#include "utils.h" + +void myalarm(){ + kill(0, SIGKILL); +} + +int main(int argc, char **argv) { + int i=0; + int seed = -1; + int array_size = -1; + int pnum = -1; + bool with_files = false; + int timeout = 0; + + while (true) { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"seed", required_argument, 0, 0}, + {"array_size", required_argument, 0, 0}, + {"pnum", required_argument, 0, 0}, + {"by_files", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "f", options, &option_index); + + if (c == -1) break; + + switch (c) { + case 0: + switch (option_index) { + case 0: + seed = atoi(optarg); + // your code here + // error handling + if (seed <= 0) { + printf("seed is a positive number\n"); + return 1; + } + break; + case 1: + array_size = atoi(optarg); + // your code here + // error handling + if (array_size <= 0) { + printf("array_size is a positive number\n"); + return 1; + } + break; + case 2: + pnum = atoi(optarg); + // your code here + // error handling + if (pnum <= 0) { + printf("pnum is a positive number\n"); + return 1; + } + break; + case 3: + with_files = true; + break; + case 4: + timeout = atoi(optarg); + if (timeout < 0) { + printf("timeout is a positive number\n"); + return 1; + } + break; + + default: + printf("Index %d is out of options\n", option_index); + } + break; + case 'f': + with_files = true; + break; + + case '?': + break; + + default: + printf("getopt returned character code 0%o?\n", c); + } + } + + if (optind < argc) { + printf("Has at least one no option argument\n"); + return 1; + } + + if (seed == -1 || array_size == -1 || pnum == -1) { + printf("Usage: %s --seed \"num\" --array_size \"num\" --pnum \"num\" \n", + argv[0]); + return 1; + } + + int *array = malloc(sizeof(int) * array_size); + GenerateArray(array, array_size, seed); + + int active_child_processes = 0; + + struct timeval start_time; + gettimeofday(&start_time, NULL); + int file_pipe_min[2]; + int file_pipe_max[2]; + if (pipe(file_pipe_min)<0) + {exit(0);} + if (pipe(file_pipe_max)<0) + {exit(0);} + + for (i = 0; i < pnum; i++) { + pid_t child_pid = fork(); + if (child_pid >= 0) { + // successful fork + active_child_processes += 1; + if (child_pid == 0) { + // child process + // parallel somehow + sleep(10); + struct MinMax min_max = GetMinMax(array,0,array_size); + if (with_files) { + FILE *f; + f=fopen("min_max.txt","w"); + char buf[33]; + sprintf(buf,"%d",min_max.min); + fprintf(f,buf); + fprintf(f,"\n"); + sprintf(buf,"%d",min_max.max); + fprintf(f,buf); + fprintf(f,"\n"); + } else { + // use pipe here + char buf[256]; + sprintf(buf,"%d",min_max.min); + write(file_pipe_min[1],buf,30); + //printf("%s\n", buf); + sprintf(buf,"%d",min_max.max); + write(file_pipe_max[1],buf,30); + //printf("%s\n", buf); + } + return 0; + } + + } else { + printf("Fork failed!\n"); + return 1; + } + } + if(timeout > 0){ + signal(14, myalarm); + alarm(timeout); + } + + int status; + while (active_child_processes > 0) { + // your code here + waitpid(-1, &status, WNOHANG); + active_child_processes -= 1; + } + + struct MinMax min_max; + min_max.min = INT_MAX; + min_max.max = INT_MIN; + + for (i = 0; i < pnum; i++) { + int min = INT_MAX; + int max = INT_MIN; + + if (with_files) { + FILE *f = fopen("min_max.txt","r"); + char buf[256]; + int a; + fscanf(f,"%s",buf); + //printf("%s\n",buf); + a=atoi(buf); + if (min>a) min=a; + fscanf(f,"%s",buf); + //printf("%s\n",buf); + a=atoi(buf); + if (max<a) max=a; + } else { + // read from pipes + char buf[256]; + int a; + read(file_pipe_min[0],buf,30); + //printf("%s\n",buf); + a=atoi(buf); + if (min>a) min=a; + read(file_pipe_max[0],buf,30); + //printf("\n%s\n",buf); + a=atoi(buf); + if (max<a) max=a; + } + + if (min < min_max.min) min_max.min = min; + if (max > min_max.max) min_max.max = max; + } + + struct timeval finish_time; + gettimeofday(&finish_time, NULL); + + double elapsed_time = (finish_time.tv_sec - start_time.tv_sec) * 1000.0; + elapsed_time += (finish_time.tv_usec - start_time.tv_usec) / 1000.0; + + free(array); + + printf("Min: %d\n", min_max.min); + printf("Max: %d\n", min_max.max); + printf("Elapsed time: %fms\n", elapsed_time); + fflush(NULL); + return 0; +}