Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stats-time command #31

Merged
merged 6 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@

char **parse_command(char *command, int *counter, char *delim);

int *parse_pids(char **pids, int N);

#endif // PARSER_H
4 changes: 3 additions & 1 deletion include/requests.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef struct REQUESTS_ARRAY {
} REQUESTS_ARRAY;

int deal_with_request(
REQUESTS_ARRAY *requests_array, PROGRAM_INFO *info, REQUEST_TYPE type
REQUESTS_ARRAY *requests_array, void *data, REQUEST_TYPE type
);

REQUESTS_ARRAY *create_requests_array(size_t size);
Expand All @@ -40,4 +40,6 @@ REQUEST *create_request(

ssize_t store_request(REQUESTS_ARRAY *requests_array, PROGRAM_INFO *info);

int stats_time_request(PIDS_ARR *pids_arr, int n_pids);

#endif // REQUESTS_H
6 changes: 6 additions & 0 deletions include/tracer.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#ifndef TRACER_H
#define TRACER_H

#include "utils.h"

int execute_program(char *full_program, char **parsed_program, int monitor_fd);

int execute_status(int monitor_fd);

int execute_pipeline(
char *pipeline, char **parsed_pipeline, int pipeline_cmds_count,
int monitor_fd
);

int execute_stats_time(int monitor_fd, PIDS_ARR *pids_arr);

#endif // TRACER_H
17 changes: 16 additions & 1 deletion include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef enum request_type {
NEW,
PIPELINE,
STATUS,
STATS_TIME,
UPDATE,
ERROR,
DONE,
Expand All @@ -30,12 +31,20 @@ typedef struct header {
size_t size;
} HEADER;

typedef struct pids_arr {
int pids[32];
int n_pids;
int child_pid;
} PIDS_ARR;

PROGRAM_INFO *create_program_info(
pid_t pid, char *name, struct timeval timestamp
);

HEADER *create_header(REQUEST_TYPE type, size_t size);

PIDS_ARR *create_pids_arr(int pids[32], int n_pids, int child_pid);

void make_fifo(char *fifo_name);

char *create_fifo(pid_t pid);
Expand All @@ -46,7 +55,7 @@ void close_fifo(int fd);

ssize_t write_to_fd(int fd, void *info, size_t size, REQUEST_TYPE type);

REQUEST_TYPE read_from_fd(int fd, void *info, size_t size);
void *read_from_fd(int fd, REQUEST_TYPE *type);

int open_file_by_path(char *path, int flags, mode_t mode);

Expand All @@ -58,4 +67,10 @@ int timeval_subtract(
struct timeval *result, struct timeval *x, struct timeval *y
);

int *parse_pids(char **pids, int N);

void divide_files_per_fork(int num_files, int *num_forks, int *files_per_fork);

int retrieve_time_from_file(int fd);

#endif // UTILS_H
7 changes: 4 additions & 3 deletions src/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ int main(int argc, char **argv) {

while (true) {
// Read data from the named pipe
PROGRAM_INFO *info = malloc(sizeof(PROGRAM_INFO));
REQUEST_TYPE type = read_from_fd(fd, info, sizeof(PROGRAM_INFO));
REQUEST_TYPE *type = malloc(sizeof(REQUEST_TYPE));
void *info = read_from_fd(fd, type);

deal_with_request(requests_array, info, type);
deal_with_request(requests_array, info, *type);

free(info);
free(type);
}

// Close the named pipes
Expand Down
13 changes: 13 additions & 0 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char **parse_command(char *command, int *counter, char *delim) {
char **parsed_command = malloc(sizeof(char *));
Expand All @@ -25,3 +26,15 @@ char **parse_command(char *command, int *counter, char *delim) {

return parsed_command;
}

// Returns an array of integers (int *)
int *parse_pids(char **pids, int N) {
int *parsed_pids = malloc(sizeof(int) * N);

for (int i = 0; i < N; i++) {
char *pid = strtok(pids[i], "PID-");
parsed_pids[i] = atoi(pid);
}

return parsed_pids;
}
85 changes: 82 additions & 3 deletions src/requests.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "monitor.h"
Expand Down Expand Up @@ -101,30 +102,43 @@ int find_request(REQUESTS_ARRAY *requests_array, pid_t pid) {
}

int deal_with_request(
REQUESTS_ARRAY *requests_array, PROGRAM_INFO *info, REQUEST_TYPE type
REQUESTS_ARRAY *requests_array, void *data, REQUEST_TYPE type
) {
int to_return = 0;

if (type == NEW || type == PIPELINE) {
PROGRAM_INFO *info = (PROGRAM_INFO *)data;
printf(
"%s request (%d) - '%s'\n", type == NEW ? "New" : "Pipeline", info->pid,
info->name
);
to_return = insert_request(requests_array, info);
} else if (type == UPDATE) {
PROGRAM_INFO *info = (PROGRAM_INFO *)data;
printf("Update request (%d) - '%s'\n", info->pid, info->name);
to_return = update_request(requests_array, info);

store_request(requests_array, info);
} else if (type == STATUS) {
PROGRAM_INFO *info = (PROGRAM_INFO *)data;
printf("Status request (%d)\n", info->pid);
pid_t pid = fork();
if (pid == 0) {
status_request(requests_array, info);
exit(EXIT_SUCCESS);
}
} else if (type == STATS_TIME) {
PIDS_ARR *pids_arr = (PIDS_ARR *)data;
printf(
"Stats time request with %d pids (%d)\n", pids_arr->n_pids,
pids_arr->child_pid
);
pid_t pid = fork();
if (pid == 0) {
stats_time_request(pids_arr, pids_arr->n_pids);
exit(EXIT_SUCCESS);
}
} else {
puts("Invalid request type received");
printf("Invalid request type received (%d)\n", type);
exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -186,3 +200,68 @@ ssize_t store_request(REQUESTS_ARRAY *requests_array, PROGRAM_INFO *info) {

return simple_write_to_fd(fd, data, strlen(data));
}

int stats_time_request(PIDS_ARR *pids_arr, int n_pids) {
int num_forks, files_per_fork;
divide_files_per_fork(n_pids, &num_forks, &files_per_fork);

// pipe from childs to comunicate with parent
int pipe_fd[2];
pipe(pipe_fd);

// Create and use num_forks forks to search for the files
for (int i = 0; i < num_forks; i++) {
pid_t pid = fork();
if (pid == 0) {
close(pipe_fd[0]); // Close stdin on child
int total_time = 0;

// Each fork will search for files_per_fork files
for (int j = 0; j < files_per_fork; j++) {
int index = i * files_per_fork + j;
if (index >= n_pids) {
break;
}

char *pid_str = malloc(sizeof(char) * 64);
sprintf(pid_str, "%s/%d", folder, pids_arr->pids[index]); // NOLINT

int fd = open_file_by_path(pid_str, O_RDONLY, 0644);
int time = retrieve_time_from_file(fd);
if (time != -1) {
total_time += time;
}

// Clean resources
free(pid_str);
close(fd);
}

simple_write_to_fd(pipe_fd[1], &total_time, sizeof(int));

exit(EXIT_SUCCESS);
}
}

close(pipe_fd[1]); // Close stdout on parent

// Accumulate total time
int total_time = 0;
for (int i = 0; i < num_forks; i++) {
int value;
int bytes_read = read(pipe_fd[0], &value, sizeof(int));

if (bytes_read != 0) {
total_time += value;
}
}

char *fifo_name = malloc(sizeof(char) * 64);
sprintf(fifo_name, "tmp/%d.fifo", pids_arr->child_pid); // NOLINT

int fd;
open_fifo(&fd, fifo_name, O_WRONLY);
write_to_fd(fd, &total_time, sizeof(int), STATS_TIME);

return 0;
}
44 changes: 38 additions & 6 deletions src/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ int main(int argc, char **argv) {
perror("execute_status");
exit(EXIT_FAILURE);
}
} else if (!strcmp(option, "stats-time")) {
int n_pids = argc - 2;
if (n_pids == 0) {
printf("Usage: %s stats-time <PID-123> <PID-456> ...\n", argv[0]);
exit(EXIT_FAILURE);
}

char **pids = argv + 2;
int *parsed_pids = parse_pids(pids, n_pids);
PIDS_ARR *pids_arr = create_pids_arr(parsed_pids, n_pids, getpid());

if (execute_stats_time(monitor_fd, pids_arr) == -1) {
perror("execute_stats_time");
exit(EXIT_FAILURE);
}
}

exit(EXIT_SUCCESS);
Expand Down Expand Up @@ -102,8 +117,9 @@ int execute_program(char *full_program, char **parsed_program, int monitor_fd) {
// Child finished

// Ensure server answered with OK
REQUEST_TYPE response = read_from_fd(pid_fd, NULL, sizeof(HEADER));
if (response != OK) {
REQUEST_TYPE *type = malloc(sizeof(REQUEST_TYPE));
read_from_fd(pid_fd, type);
if (*type != OK) {
printf("Server answered with an error\n");
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -143,11 +159,13 @@ int execute_status(int monitor_fd) {
int pid_fd;
open_fifo(&pid_fd, fifo_name, O_RDONLY);

REQUEST *answer_data = malloc(sizeof(REQUEST));
while (read_from_fd(pid_fd, answer_data, sizeof(REQUEST)) != DONE) {
REQUEST_TYPE *type = malloc(sizeof(REQUEST_TYPE));
REQUEST *answer_data = read_from_fd(pid_fd, type);
while (*type != DONE) {
printf(
"Program '%s' running (%d)\n", answer_data->command, answer_data->pid
);
answer_data = read_from_fd(pid_fd, type);
}

// Clean resources
Expand Down Expand Up @@ -263,8 +281,9 @@ int execute_pipeline(
close(original_stdout);

// Ensure server answered with OK
REQUEST_TYPE response = read_from_fd(pid_fd, NULL, sizeof(HEADER));
if (response != OK) {
REQUEST_TYPE *type = malloc(sizeof(REQUEST_TYPE));
read_from_fd(pid_fd, type);
if (*type != OK) {
printf("Server answered with an error\n");
exit(EXIT_FAILURE);
}
Expand All @@ -287,3 +306,16 @@ int execute_pipeline(
exit(EXIT_FAILURE);
}
}

int execute_stats_time(int monitor_fd, PIDS_ARR *pids_arr) {
write_to_fd(monitor_fd, pids_arr, sizeof(PIDS_ARR), STATS_TIME);

char *fifo_name = create_fifo(pids_arr->child_pid);
int pid_fd;
open_fifo(&pid_fd, fifo_name, O_RDONLY);
int *answer_data = read_from_fd(pid_fd, NULL);

printf("Total execution time is %d ms\n", *answer_data);

return 0;
}
Loading