Skip to content

Commit afbeca8

Browse files
committed
Add notify watchdog
Add terminating threads Remove clang warnings
1 parent 1157972 commit afbeca8

File tree

8 files changed

+74
-40
lines changed

8 files changed

+74
-40
lines changed

.gdb_history

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ run
1010
quit
1111
run
1212
quit
13+
run
14+
quit

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ cputracker.o
88
cputracker
99
analyzer.o
1010
printer.o
11+
out
12+
.gdb_history

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
CC = gcc -g
2-
CFLAGS = -O3 -Wall -Werror -pthread
3-
# CC = clang
4-
# CFLAGS = -Weverything -pthread
1+
# CC = gcc -g
2+
# CFLAGS = -O3 -Wall -Werror -pthread
3+
CC = clang
4+
CFLAGS = -Weverything -pthread
55

66
OBJS = reader.o cputracker.o analyzer.o printer.o
77

analyzer.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,26 @@ static unsigned long average_cpu_usage(struct proc_stat prev,
2121
}
2222

2323
void *analyzer(void *arg) {
24-
struct proc_stat *prev =
25-
malloc((unsigned long)g_nproc * sizeof(struct proc_stat));
26-
if (prev == NULL) {
24+
struct proc_stat *prev;
25+
unsigned long *avg;
26+
unsigned long *bufforAvg;
27+
struct proc_stat *stats;
28+
29+
(void)arg;
30+
31+
if ((prev = malloc((unsigned long)g_nproc * sizeof(struct proc_stat))) == NULL) {
2732
return NULL;
2833
}
29-
unsigned long *avg = malloc((unsigned long)g_nproc * sizeof(unsigned long));
30-
if (avg == NULL) {
34+
if ((avg = malloc((unsigned long)g_nproc * sizeof(unsigned long))) == NULL) {
3135
free(prev);
3236
return NULL;
3337
}
34-
unsigned long *bufforAvg;
35-
struct proc_stat *stats = NULL;
36-
pthread_cleanup_push(free, prev);
37-
pthread_cleanup_push(free, avg);
38+
pthread_cleanup_push(free, prev)
39+
pthread_cleanup_push(free, avg)
3840
while (1) {
39-
sem_wait(&g_dataFilledSpaceSemaphore);
41+
notify_watchdog(Analyzer);
4042

43+
sem_wait(&g_dataFilledSpaceSemaphore);
4144
pthread_mutex_lock(&g_dataBufferMutex);
4245

4346
stats = get_item_from_data_buffer();
@@ -47,23 +50,19 @@ void *analyzer(void *arg) {
4750
}
4851

4952
pthread_mutex_unlock(&g_dataBufferMutex);
50-
5153
sem_post(&g_dataLeftSpaceSemaphore);
5254

5355
//
5456

5557
sem_wait(&g_printLeftSpaceSemaphore);
56-
5758
pthread_mutex_lock(&g_printBufferMutex);
5859

5960
bufforAvg = get_item_from_print_buffer();
6061
memcpy(bufforAvg, avg, (unsigned long)g_nproc * sizeof(unsigned long));
6162

6263
pthread_mutex_unlock(&g_printBufferMutex);
63-
6464
sem_post(&g_printFilledSpaceSemaphore);
6565
}
6666
pthread_cleanup_pop(1);
6767
pthread_cleanup_pop(1);
68-
return arg;
6968
}

cputracker.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "printer.h"
44
#include "reader.h"
55

6+
67
int g_nproc = 0;
78
static struct proc_stat *g_dataBuffer[BUFFER_SIZE];
89
pthread_mutex_t g_dataBufferMutex = PTHREAD_MUTEX_INITIALIZER;
@@ -18,7 +19,12 @@ static pthread_t readerThreadId;
1819
static pthread_t analyzerThreadId;
1920
static pthread_t printerThreadId;
2021

21-
void handler(int signum) {
22+
23+
static int working[THREADS];
24+
static pthread_mutex_t watchdogMutex = PTHREAD_MUTEX_INITIALIZER;
25+
26+
static void handler(int signum) {
27+
(void)signum;
2228
pthread_cancel(readerThreadId);
2329
pthread_cancel(printerThreadId);
2430
pthread_cancel(analyzerThreadId);
@@ -48,7 +54,34 @@ unsigned long *get_item_from_print_buffer(void) {
4854
return g_printBuffer[index];
4955
}
5056

57+
void notify_watchdog(int id){
58+
pthread_mutex_lock(&watchdogMutex);
59+
working[id] = 1;
60+
pthread_mutex_unlock(&watchdogMutex);
61+
}
62+
63+
static void watchdog(void) {
64+
while (1) {
65+
sleep(TIMEOUT);
66+
pthread_mutex_lock(&watchdogMutex);
67+
for (int i = 0; i < THREADS; i++) {
68+
if (working[i] == 0) {
69+
pthread_mutex_unlock(&watchdogMutex);
70+
perror("Error: Thread not responding... Terminating\n");
71+
handler(-1);
72+
return;
73+
}
74+
working[i] = 0;
75+
}
76+
pthread_mutex_unlock(&watchdogMutex);
77+
}
78+
}
79+
80+
5181
int main(void) {
82+
struct sigaction action;
83+
memset(&action, 0, sizeof(struct sigaction));
84+
5285
if (get_nproc(&g_nproc) == -1) {
5386
exit(EXIT_FAILURE);
5487
}
@@ -76,11 +109,11 @@ int main(void) {
76109
pthread_create(&analyzerThreadId, NULL, analyzer, NULL);
77110
pthread_create(&printerThreadId, NULL, printer, NULL);
78111

79-
struct sigaction action;
80-
memset(&action, 0, sizeof(struct sigaction));
81112
action.sa_handler = handler;
82113
sigaction(SIGTERM, &action, NULL);
83114

115+
watchdog();
116+
84117
pthread_join(readerThreadId, NULL);
85118
pthread_join(analyzerThreadId, NULL);
86119
pthread_join(printerThreadId, NULL);
@@ -92,6 +125,8 @@ int main(void) {
92125
pthread_mutex_destroy(&g_printBufferMutex);
93126
sem_destroy(&g_printFilledSpaceSemaphore);
94127
sem_destroy(&g_printLeftSpaceSemaphore);
128+
129+
pthread_mutex_destroy(&watchdogMutex);
95130
for (int i = 0; i < BUFFER_SIZE; i++) {
96131
free(g_dataBuffer[i]);
97132
free(g_printBuffer[i]);

cputracker.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
#define EXIT_FAILURE 1
1616
#define EXIT_SUCCESS 0
1717

18+
#define TIMEOUT 2
19+
#define THREADS 3
20+
21+
enum State {Reader = 0, Printer = 1, Analyzer = 2};
22+
1823
struct proc_stat {
1924
char name[256];
2025
unsigned long user, // Time spent with normal processing in user mode.
@@ -33,7 +38,6 @@ struct proc_stat {
3338
// operating systems under the control of the Linux kernel).
3439
};
3540

36-
extern volatile sig_atomic_t done;
3741

3842
extern int g_nproc;
3943
extern pthread_mutex_t g_dataBufferMutex;
@@ -46,4 +50,5 @@ extern sem_t g_printLeftSpaceSemaphore;
4650

4751
unsigned long *get_item_from_print_buffer(void);
4852
struct proc_stat *get_item_from_data_buffer(void);
53+
void notify_watchdog(int id);
4954
#endif

printer.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
11
#include "printer.h"
22

33
void *printer(void *arg) {
4-
unsigned long *avg = NULL;
4+
unsigned long *avg;
5+
(void)arg;
56
while (1) {
7+
notify_watchdog(Printer);
68
sem_wait(&g_printFilledSpaceSemaphore);
7-
89
pthread_mutex_lock(&g_printBufferMutex);
910

1011
system("clear");
11-
1212
avg = get_item_from_print_buffer();
13-
1413
printf("CORE\t%%\n");
1514
for (int i = 0; i < g_nproc; i++) {
1615
printf("[%2d]: \033[38;2;%lu;%lu;0m%3lu\033[0m\n", i, avg[i] * 5 / 2,
1716
255 - avg[i] * 5 / 2, avg[i]);
1817
}
19-
18+
2019
pthread_mutex_unlock(&g_printBufferMutex);
21-
2220
sem_post(&g_printLeftSpaceSemaphore);
2321
sleep(1);
2422
}
25-
return arg;
2623
}

reader.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "reader.h"
2-
#include <pthread.h>
2+
#include "cputracker.h"
33

44
static int get_proc_stats(struct proc_stat *stats) {
55
FILE *file = fopen("/proc/stat", "r");
@@ -10,7 +10,6 @@ static int get_proc_stats(struct proc_stat *stats) {
1010
fclose(file);
1111
return -1;
1212
}
13-
1413
sscanf(line, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
1514
stats[thread].name, &stats[thread].user, &stats[thread].nice,
1615
&stats[thread].system, &stats[thread].idle, &stats[thread].iowait,
@@ -22,25 +21,20 @@ static int get_proc_stats(struct proc_stat *stats) {
2221
}
2322

2423
void *reader(void *arg) {
25-
struct proc_stat *stats = NULL;
24+
(void)arg;
2625
while (1) {
27-
26+
notify_watchdog(Reader);
2827
sem_wait(&g_dataLeftSpaceSemaphore);
29-
3028
pthread_mutex_lock(&g_dataBufferMutex);
3129

32-
stats = get_item_from_data_buffer();
33-
34-
if (get_proc_stats(stats) == -1) {
30+
if (get_proc_stats(get_item_from_data_buffer()) == -1) {
3531
pthread_mutex_unlock(&g_dataBufferMutex);
3632
sem_post(&g_dataLeftSpaceSemaphore);
3733
continue;
3834
}
39-
35+
4036
pthread_mutex_unlock(&g_dataBufferMutex);
41-
4237
sem_post(&g_dataFilledSpaceSemaphore);
4338
usleep(READ_DELAY);
4439
}
45-
return arg;
4640
}

0 commit comments

Comments
 (0)