Skip to content

Commit bf252e5

Browse files
committed
Add printer thread
1 parent dff3164 commit bf252e5

File tree

9 files changed

+128
-48
lines changed

9 files changed

+128
-48
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ reader.o
77
cputracker.o
88
cputracker
99
analyzer.o
10+
printer.o

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
CC = gcc -g
22
CFLAGS = -O3 -Wall -Werror
33

4-
OBJS = reader.o cputracker.o analyzer.o
4+
OBJS = reader.o cputracker.o analyzer.o printer.o
55

66
reader: $(OBJS)
77
$(CC) $(CFLAGS) -o cputracker $(OBJS)
88

99
reader.o: reader.c reader.h cputracker.h
1010
analyzer.o: analyzer.c analyzer.h cputracker.h
11+
printer.o: printer.c printer.h cputracker.h
1112
cputracker.o: cputracker.c reader.h cputracker.h
1213

1314
format:

analyzer.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,58 @@
11
#include "analyzer.h"
22
#include "cputracker.h"
3+
#include <stdlib.h>
4+
#include <unistd.h>
35

4-
unsigned long average_cpu_usage(struct proc_stat prev, struct proc_stat next) {
5-
unsigned long prev_idle = prev.idle + prev.iowait;
6-
unsigned long idle = next.idle + next.iowait;
6+
unsigned long average_cpu_usage(struct proc_stat prev, struct proc_stat current) {
7+
unsigned long prevIdle = prev.idle + prev.iowait;
8+
unsigned long idle = current.idle + current.iowait;
79

8-
unsigned long prev_non_idle = prev.user + prev.nice + prev.system + prev.irq +
10+
unsigned long prevNonIdle = prev.user + prev.nice + prev.system + prev.irq +
911
prev.softirq + prev.steal;
10-
unsigned long non_idle = next.user + next.nice + next.system + next.irq +
11-
next.softirq + next.steal;
12+
unsigned long nonIdle = current.user + current.nice + current.system + current.irq +
13+
current.softirq + current.steal;
1214

13-
unsigned long prev_total = prev_idle + prev_non_idle;
14-
unsigned long total = idle + non_idle;
15+
unsigned long prevTotal = prevIdle + prevNonIdle;
16+
unsigned long total = idle + nonIdle;
1517

16-
total -= prev_total;
17-
idle -= prev_idle;
18+
total -= prevTotal;
19+
idle -= prevIdle;
1820

1921
return (total - idle) * 100 / total;
2022
}
2123

2224
void *analyzer() {
2325
struct proc_stat *prev = malloc(g_nproc * sizeof(struct proc_stat));
26+
unsigned long *avg = malloc(g_nproc * sizeof(unsigned long));
2427
struct proc_stat *stats = NULL;
2528
while (1) {
26-
sem_wait(&g_filledSpaceSemaphore);
29+
sem_wait(&g_dataFilledSpaceSemaphore);
2730

28-
pthread_mutex_lock(&g_bufferMutex);
31+
pthread_mutex_lock(&g_dataBufferMutex);
2932

30-
stats = get_item_from_buffer();
33+
stats = get_item_from_data_buffer();
3134
for (int i = 0; i < g_nproc; i++) {
32-
printf("%lu ", average_cpu_usage(prev[i], stats[i]));
35+
avg[i] = average_cpu_usage(prev[i], stats[i]);
3336
prev[i] = stats[i];
3437
}
3538

36-
printf("\n");
37-
pthread_mutex_unlock(&g_bufferMutex);
39+
pthread_mutex_unlock(&g_dataBufferMutex);
3840

39-
sem_post(&g_leftSpaceSemaphore);
41+
sem_post(&g_dataLeftSpaceSemaphore);
42+
43+
//
44+
45+
sem_wait(&g_printLeftSpaceSemaphore);
46+
47+
pthread_mutex_lock(&g_printBufferMutex);
48+
49+
unsigned long *bufforAvg = get_item_from_print_buffer();
50+
memcpy(bufforAvg, avg, g_nproc*sizeof(unsigned long));
51+
52+
pthread_mutex_unlock(&g_printBufferMutex);
53+
54+
sem_post(&g_printFilledSpaceSemaphore);
4055
}
4156
free(prev);
57+
free(avg);
4258
}

cputracker.c

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
#include "cputracker.h"
22
#include "analyzer.h"
33
#include "reader.h"
4+
#include "printer.h"
45

56
int g_nproc = 0;
6-
struct proc_stat *g_buffer[BUFFER_SIZE];
7-
pthread_mutex_t g_bufferMutex = PTHREAD_MUTEX_INITIALIZER;
8-
sem_t g_filledSpaceSemaphore;
9-
sem_t g_leftSpaceSemaphore;
7+
struct proc_stat *g_dataBuffer[BUFFER_SIZE];
8+
pthread_mutex_t g_dataBufferMutex = PTHREAD_MUTEX_INITIALIZER;
9+
sem_t g_dataFilledSpaceSemaphore;
10+
sem_t g_dataLeftSpaceSemaphore;
11+
12+
13+
unsigned long *g_printBuffer[BUFFER_SIZE];
14+
pthread_mutex_t g_printBufferMutex = PTHREAD_MUTEX_INITIALIZER;
15+
sem_t g_printFilledSpaceSemaphore;
16+
sem_t g_printLeftSpaceSemaphore;
17+
18+
pthread_t readerThreadId;
19+
pthread_t analyzerThreadId;
20+
pthread_t printerThreadId;
1021

1122
int get_nproc(int *nproc) {
1223
*nproc = sysconf(_SC_NPROCESSORS_ONLN);
@@ -22,9 +33,14 @@ int get_semaphore_value(sem_t *sem) {
2233
return sval;
2334
}
2435

25-
struct proc_stat *get_item_from_buffer() {
26-
int index = get_semaphore_value(&g_filledSpaceSemaphore);
27-
return g_buffer[index];
36+
struct proc_stat *get_item_from_data_buffer() {
37+
int index = get_semaphore_value(&g_dataFilledSpaceSemaphore);
38+
return g_dataBuffer[index];
39+
}
40+
41+
unsigned long *get_item_from_print_buffer() {
42+
int index = get_semaphore_value(&g_printFilledSpaceSemaphore);
43+
return g_printBuffer[index];
2844
}
2945

3046
int main() {
@@ -34,29 +50,41 @@ int main() {
3450
g_nproc++;
3551

3652
for (int i = 0; i < BUFFER_SIZE; i++) {
37-
g_buffer[i] = malloc(g_nproc * sizeof(struct proc_stat));
38-
if (g_buffer[i] == NULL) {
53+
g_dataBuffer[i] = malloc(g_nproc * sizeof(struct proc_stat));
54+
g_printBuffer[i] = malloc(g_nproc * sizeof(unsigned long));
55+
if (g_dataBuffer[i] == NULL || g_printBuffer[i] == NULL) {
3956
exit(EXIT_FAILURE);
4057
}
4158
}
4259

43-
if (sem_init(&g_filledSpaceSemaphore, 0, 0) ||
44-
sem_init(&g_leftSpaceSemaphore, 0, BUFFER_SIZE)) {
60+
if (sem_init(&g_dataFilledSpaceSemaphore, 0, 0) ||
61+
sem_init(&g_dataLeftSpaceSemaphore, 0, BUFFER_SIZE)) {
62+
exit(EXIT_FAILURE);
63+
}
64+
65+
if (sem_init(&g_printFilledSpaceSemaphore, 0, 0) ||
66+
sem_init(&g_printLeftSpaceSemaphore, 0, BUFFER_SIZE)) {
4567
exit(EXIT_FAILURE);
4668
}
4769

48-
pthread_t readerThreadId;
49-
pthread_t analyzerThreadId;
5070
pthread_create(&readerThreadId, NULL, reader, NULL);
5171
pthread_create(&analyzerThreadId, NULL, analyzer, NULL);
72+
pthread_create(&printerThreadId, NULL, printer, NULL);
73+
5274
pthread_join(readerThreadId, NULL);
5375
pthread_join(analyzerThreadId, NULL);
76+
pthread_join(printerThreadId, NULL);
77+
78+
pthread_mutex_destroy(&g_dataBufferMutex);
79+
sem_destroy(&g_dataFilledSpaceSemaphore);
80+
sem_destroy(&g_dataLeftSpaceSemaphore);
5481

55-
pthread_mutex_destroy(&g_bufferMutex);
56-
sem_destroy(&g_filledSpaceSemaphore);
57-
sem_destroy(&g_leftSpaceSemaphore);
82+
pthread_mutex_destroy(&g_printBufferMutex);
83+
sem_destroy(&g_printFilledSpaceSemaphore);
84+
sem_destroy(&g_printLeftSpaceSemaphore);
5885
for (int i = 0; i < BUFFER_SIZE; i++) {
59-
free(g_buffer[i]);
86+
free(g_dataBuffer[i]);
87+
free(g_printBuffer[i]);
6088
}
6189
return 0;
6290
}

cputracker.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <string.h>
1111
#include <unistd.h>
1212

13-
#define BUFFER_SIZE 100
13+
#define BUFFER_SIZE 5
1414

1515
#define EXIT_FAILURE 1
1616
#define EXIT_SUCCESS 0
@@ -34,12 +34,19 @@ struct proc_stat {
3434
};
3535

3636
extern int g_nproc;
37-
extern struct proc_stat *g_buffer[];
38-
extern pthread_mutex_t g_bufferMutex;
39-
extern sem_t g_filledSpaceSemaphore;
40-
extern sem_t g_leftSpaceSemaphore;
37+
extern struct proc_stat *g_dataBuffer[];
38+
extern pthread_mutex_t g_dataBufferMutex;
39+
extern sem_t g_dataFilledSpaceSemaphore;
40+
extern sem_t g_dataLeftSpaceSemaphore;
41+
42+
43+
extern unsigned long *g_printBuffer[BUFFER_SIZE];
44+
extern pthread_mutex_t g_printBufferMutex;
45+
extern sem_t g_printFilledSpaceSemaphore;
46+
extern sem_t g_printLeftSpaceSemaphore;
4147

4248
int get_nproc(int *nproc);
4349
int get_semaphore_value(sem_t *sem);
44-
struct proc_stat *get_item_from_buffer();
50+
unsigned long *get_item_from_print_buffer();
51+
struct proc_stat *get_item_from_data_buffer();
4552
#endif

printer.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "printer.h"
2+
3+
void *printer() {
4+
unsigned long *avg = NULL;
5+
while (1) {
6+
sem_wait(&g_printFilledSpaceSemaphore);
7+
8+
pthread_mutex_lock(&g_printBufferMutex);
9+
10+
system("clear");
11+
avg = get_item_from_print_buffer();
12+
for (int i = 0; i < g_nproc; i++) {
13+
printf("[%d]: \033[38;2;%lu;%lu;0m%lu\033[0m\n", i,avg[i]*5/2,255-avg[i]*5/2, avg[i]);
14+
}
15+
16+
pthread_mutex_unlock(&g_printBufferMutex);
17+
18+
sem_post(&g_printLeftSpaceSemaphore);
19+
sleep(1);
20+
}
21+
}

printer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef PRINTER_H
2+
#define PRINTER_H
3+
#include "cputracker.h"
4+
5+
void *printer();
6+
#endif

reader.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ void *reader() {
2525
struct proc_stat *stats = NULL;
2626
while (1) {
2727

28-
sem_wait(&g_leftSpaceSemaphore);
28+
sem_wait(&g_dataLeftSpaceSemaphore);
2929

30-
pthread_mutex_lock(&g_bufferMutex);
30+
pthread_mutex_lock(&g_dataBufferMutex);
3131

32-
stats = get_item_from_buffer();
32+
stats = get_item_from_data_buffer();
3333

3434
if (get_proc_stats(stats) == -1) {
35-
pthread_mutex_unlock(&g_bufferMutex);
35+
pthread_mutex_unlock(&g_dataBufferMutex);
3636
continue;
3737
}
3838

39-
pthread_mutex_unlock(&g_bufferMutex);
39+
pthread_mutex_unlock(&g_dataBufferMutex);
4040

41-
sem_post(&g_filledSpaceSemaphore);
41+
sem_post(&g_dataFilledSpaceSemaphore);
4242
usleep(READ_DELAY);
4343
}
4444
}

reader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define READER_H
33
#include "cputracker.h"
44

5-
#define READ_DELAY 30000
5+
#define READ_DELAY 50000
66

77
int get_proc_stats(struct proc_stat *stats);
88
void *reader();

0 commit comments

Comments
 (0)