Rework children creation and add recursive calls
This commit is contained in:
parent
446ac678db
commit
c70db7363d
194
cpair/cpair.c
194
cpair/cpair.c
@ -60,7 +60,28 @@ float get_distance(float x1, float x2, float y1, float y2);
|
||||
node_t * find_shortest_distance(node_t * list);
|
||||
int wait_for_termination(pid_t child);
|
||||
|
||||
int main(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc > 1) {
|
||||
puts("The command takes no additional arguments.");
|
||||
puts("Usage: cpair");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Process id: %d\n", getpid());
|
||||
/**
|
||||
* Create the pipe file descriptors and inititalize the pipes
|
||||
*
|
||||
* fd[0] - input side of pipe
|
||||
* fd[1] - output side of pipe
|
||||
*
|
||||
**/
|
||||
int in_pipe_a[2], out_pipe_a[2], in_pipe_b[2], out_pipe_b[2];
|
||||
|
||||
if(pipe(in_pipe_a) < 0 || pipe(in_pipe_b) < 0 || pipe(out_pipe_a) < 0 || pipe(out_pipe_b) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed creating the pipes\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char input[__UINT8_MAX__] = ""; ///< An array to save the input to
|
||||
int point_num = 0; ///< Save the number of points
|
||||
node_t * head = NULL;
|
||||
@ -101,101 +122,126 @@ int main(void) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
float x_mean = get_x_mean(head);
|
||||
|
||||
node_t * first_part = malloc(sizeof(node_t));
|
||||
node_t * second_part = malloc(sizeof(node_t));
|
||||
|
||||
node_t * first_part_buff = first_part;
|
||||
node_t * second_part_buff = second_part;
|
||||
|
||||
/// Separate the lists based on the mean
|
||||
current = head;
|
||||
while(current != NULL) {
|
||||
if(current -> points[0] <= x_mean) {
|
||||
first_part_buff -> points[0] = current -> points[0];
|
||||
first_part_buff -> next = malloc(sizeof(node_t));
|
||||
first_part_buff = first_part_buff -> next;
|
||||
} else {
|
||||
second_part_buff -> points[0] = current -> points[0];
|
||||
second_part_buff -> next = malloc(sizeof(node_t));
|
||||
second_part_buff = second_part_buff -> next;
|
||||
}
|
||||
current = current -> next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the pipe file descriptors and inititalize the pipes
|
||||
*
|
||||
* fd[0] - input side of pipe
|
||||
* fd[1] - output side of pipe
|
||||
*
|
||||
**/
|
||||
int pipe_a[2], pipe_b[2];
|
||||
|
||||
if(pipe(pipe_a) < 0 || pipe(pipe_b) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed creating the pipe\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pid_t child_a, child_b; ///< Create variables for the child processes
|
||||
node_t * child_a_part = NULL;
|
||||
node_t * child_b_part = NULL;
|
||||
|
||||
write(pipe_a[0], first_part, sizeof(node_t)); ///< Send the first part of the array to the child
|
||||
|
||||
/// Create first child
|
||||
switch(child_a = fork()) {
|
||||
case -1:
|
||||
fprintf(stderr ,"ERROR: Couldn't fork child\n");
|
||||
exit(EXIT_FAILURE);
|
||||
case 0:
|
||||
if(read(pipe_a[0], child_a_part, sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed reading from pipe\n");
|
||||
/// Child execution
|
||||
fprintf(stderr, "Child 1 id: %d\n", getpid());
|
||||
close(out_pipe_a[0]);
|
||||
close(in_pipe_a[1]);
|
||||
close(STDIN_FILENO);
|
||||
if(dup2(in_pipe_a[0], STDIN_FILENO) != STDIN_FILENO) {
|
||||
fprintf(stderr, "ERROR: Failed duplicating STDIN");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(write(pipe_a[1], find_shortest_distance(child_a_part), sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed writing to pipe\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
execlp(argv[0], argv[0], NULL);
|
||||
|
||||
fprintf(stderr, "ERROR: Failed to load program into child");
|
||||
exit(EXIT_FAILURE);
|
||||
default:
|
||||
write(pipe_b[0], second_part, sizeof(node_t));
|
||||
/// Parent execution
|
||||
/// Create second child
|
||||
switch(child_b = fork()) {
|
||||
case -1:
|
||||
fprintf(stderr, "ERROR: Couldn't fork child\n");
|
||||
exit(EXIT_FAILURE);
|
||||
case 0:
|
||||
if(read(pipe_b[0], child_b_part, sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed reading from pipe\n");
|
||||
/// Child execution
|
||||
fprintf(stderr, "Child 2 id: %d\n", getpid());
|
||||
close(out_pipe_b[0]);
|
||||
close(in_pipe_b[1]);
|
||||
close(STDIN_FILENO);
|
||||
if(dup2(in_pipe_b[0], STDIN_FILENO) != STDIN_FILENO) {
|
||||
fprintf(stderr, "ERROR: Failed duplicating STDIN");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(write(pipe_b[1], find_shortest_distance(child_b_part), sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed writing to pipe\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
execlp(argv[0], argv[0], NULL);
|
||||
|
||||
fprintf(stderr, "ERROR: Failed to load program into child");
|
||||
exit(EXIT_FAILURE);
|
||||
default:
|
||||
/// Parent execution
|
||||
close(in_pipe_a[0]);
|
||||
close(in_pipe_b[0]);
|
||||
close(STDOUT_FILENO);
|
||||
|
||||
float x_mean = get_x_mean(head);
|
||||
|
||||
node_t * first_part = malloc(sizeof(node_t));
|
||||
int first_part_len = 1;
|
||||
|
||||
node_t * second_part = malloc(sizeof(node_t));
|
||||
int second_part_len = 1;
|
||||
|
||||
node_t * first_part_buff = first_part;
|
||||
node_t * second_part_buff = second_part;
|
||||
|
||||
/// Separate the lists based on the mean
|
||||
current = head;
|
||||
while(current != NULL) {
|
||||
if(current -> points[0] <= x_mean) {
|
||||
first_part_buff -> points[0] = current -> points[0];
|
||||
first_part_buff -> next = malloc(sizeof(node_t));
|
||||
first_part_buff = first_part_buff -> next;
|
||||
first_part_len ++;
|
||||
} else {
|
||||
second_part_buff -> points[0] = current -> points[0];
|
||||
second_part_buff -> next = malloc(sizeof(node_t));
|
||||
second_part_buff = second_part_buff -> next;
|
||||
second_part_len ++;
|
||||
}
|
||||
current = current -> next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the correct lists to the children
|
||||
**/
|
||||
|
||||
/// First half
|
||||
if(dup2(in_pipe_a[1], STDIN_FILENO) != STDIN_FILENO) {
|
||||
fprintf(stderr, "ERROR: Failed duplicating STDIN");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (write(in_pipe_a[1], first_part_buff, first_part_len*sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed writing to child\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
close(STDOUT_FILENO);
|
||||
///Second half
|
||||
if(dup2(in_pipe_b[1], STDIN_FILENO) != STDIN_FILENO) {
|
||||
fprintf(stderr, "ERROR: Failed duplicating STDIN");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (write(in_pipe_b[1], first_part_buff, second_part_len*sizeof(node_t)) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed writing to child\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
close(STDOUT_FILENO);
|
||||
|
||||
/// Wait for the correct exit of the children
|
||||
if(wait_for_termination(child_a) != EXIT_SUCCESS || wait_for_termination(child_b) != EXIT_SUCCESS) {
|
||||
fprintf(stderr, "ERROR: Children didn't terminate successfully");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/// Free the memory
|
||||
free(head);
|
||||
free(first_part);
|
||||
free(first_part_buff);
|
||||
free(second_part);
|
||||
free(second_part_buff);
|
||||
free(current);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(wait_for_termination(child_a) != EXIT_SUCCESS)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if(wait_for_termination(child_b) != EXIT_SUCCESS)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
/// Free the memory
|
||||
free(head);
|
||||
free(first_part);
|
||||
free(first_part_buff);
|
||||
free(second_part);
|
||||
free(second_part_buff);
|
||||
free(current);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user