Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 2
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 47
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 48
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 49
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 50
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 51
/* Sistemi Operativi - prova di laboratorio
* compito del 28/07/2016 - soluzione */
#include
#include
#include
#include
#include
#include
#include
#include
#define DEFAULT_NUM_SAMPLES 30
#define PAUSE_SECS 1
#define MAX_LEN_BUFFER 1024
#define PROC_PATHNAME "/proc/stat"
#define DISPLAY_COLUMNS 60
#define RAW_DATA_MSG_TYPE 1
#define DELTA_DATA_MSG_TYPE 2
typedef struct {
long type;
long int user;
long int system;
long int idle;
} raw_msg;
typedef struct {
long type;
float user;
float system;
} delta_msg;
/* il figlio sampler che si occupa di campionare dal file-system /proc/ */
void sampler(int queue, int num_samples) {
raw_msg out_message;
FILE *proc_fs;
char buffer[MAX_LEN_BUFFER];
long int ignore_it;
out_message.type = RAW_DATA_MSG_TYPE;
for (int i = 0; i < num_samples; i++) {
if ((proc_fs = fopen(PROC_PATHNAME, "r")) == NULL) {
perror(PROC_PATHNAME);
exit(1);
}
if (fgets(buffer, MAX_LEN_BUFFER, proc_fs) == NULL) {
perror(PROC_PATHNAME);
exit(1);
}
fclose(proc_fs);
sscanf(buffer, "cpu %ld %ld %ld %ld %ld %ld %ld", &out_message.user,
&ignore_it, &out_message.system, &out_message.idle, &ignore_it,
&ignore_it, &ignore_it);
if (msgsnd(queue, &out_message,
sizeof(out_message) - sizeof(out_message.type), 0) == -1)
perror("msgsnd");
sleep(PAUSE_SECS);
}
/* invia un ultimo messaggio con dati negativi per segnalare l'EOF */
out_message.user = out_message.system = out_message.idle = -1;
if (msgsnd(queue, &out_message,
sizeof(out_message) - sizeof(out_message.type), 0) == -1)
perror("msgsnd");
exit(0);
}
/* il figlio analyzer che si occupa di tradurre i sample sugli utilizzi delle
* CPU in percentuali di variazione */
void analyzer(int queue) {
raw_msg in_message;
delta_msg out_message;
long int last_user = 0, last_system = 0, last_idle = 0;
long int total;
out_message.type = DELTA_DATA_MSG_TYPE;
while (1) {
if (msgrcv(queue, &in_message,
sizeof(in_message) - sizeof(in_message.type),
RAW_DATA_MSG_TYPE, 0) == -1)
perror("msgrcv");
if (in_message.user < 0)
break;
if (last_user != 0) {
total = (in_message.user - last_user) +
(in_message.system - last_system) +
(in_message.idle - last_idle);
out_message.user =
(float)(in_message.user - last_user) / (float)total;
out_message.system =
(float)(in_message.system - last_system) / (float)total;
if (msgsnd(queue, &out_message,
sizeof(out_message) - sizeof(out_message.type), 0) == -1)
perror("msgsnd");
}
last_user = in_message.user;
last_system = in_message.system;
last_idle = in_message.idle;
}
/* invia, a sua volta, un messaggio di EOF con dati negativi */
out_message.user = out_message.system = -1.0;
if (msgsnd(queue, &out_message,
sizeof(out_message) - sizeof(out_message.type), 0) == -1)
perror("msgsnd");
exit(0);
}
void print_chars(unsigned int n, char c) {
for (unsigned int i = 0; i < n; i++)
putc(c, stdout);
}
/* il figlio plotter che si occupa di visualizzare i dati di variazione */
void plotter(int queue) {
delta_msg in_message;
unsigned int user_chars, system_chars, idle_chars;
while (1) {
if (msgrcv(queue, &in_message,
sizeof(in_message) - sizeof(in_message.type),
DELTA_DATA_MSG_TYPE, 0) == -1)
perror("msgrcv");
if (in_message.user < 0)
break;
user_chars = in_message.user * DISPLAY_COLUMNS;
system_chars = in_message.system * DISPLAY_COLUMNS;
idle_chars = DISPLAY_COLUMNS - user_chars - system_chars;
print_chars(system_chars, '#');
print_chars(user_chars, '*');
print_chars(idle_chars, '_');
printf(" s:%5.2f%% u:%5.2f%%\n", in_message.system * 100,
in_message.user * 100);
}
exit(0);
}
int main(int argc, char **argv) {
int queue;
int num_samples;
if ((argc == 1) || ((num_samples = atoi(argv[1])) < 2))
num_samples = DEFAULT_NUM_SAMPLES;
if ((queue = msgget(IPC_PRIVATE, IPC_CREAT | 0600)) == -1) {
perror("msgget");
exit(1);
}
if (fork() == 0)
sampler(queue, num_samples);
if (fork() == 0)
analyzer(queue);
if (fork() == 0)
plotter(queue);
wait(NULL);
wait(NULL);
wait(NULL);
msgctl(queue, IPC_RMID, NULL);
exit(0);
}