|
| 1 | +#define _DEFAULT_SOURCE |
| 2 | + |
| 3 | +#include <stdatomic.h> |
1 | 4 | #include <stdbool.h>
|
2 | 5 | #include <stdlib.h>
|
3 | 6 | #include <stdio.h>
|
4 | 7 |
|
5 | 8 | #include <sys/types.h>
|
6 | 9 | #include <sys/wait.h>
|
| 10 | +#include <sys/mman.h> |
| 11 | +#include <unistd.h> |
7 | 12 |
|
8 | 13 | #include "frk.h"
|
9 | 14 |
|
| 15 | +struct shared_data { |
| 16 | + atomic_int total_threads; |
| 17 | + atomic_int total_processes; |
| 18 | +}; |
| 19 | + |
10 | 20 | static bool initialized = false;
|
11 | 21 | static int depth = 0;
|
| 22 | +static int thread_nr = 0; |
| 23 | +static struct shared_data *shared_data = NULL; |
12 | 24 |
|
13 | 25 | static void close_graph(void) {
|
14 | 26 | while(wait(NULL) != -1);
|
| 27 | + if(thread_nr > 0) { |
| 28 | + printf(" %d [xlabel=\"T: %d\"];\n", getpid(), thread_nr); |
| 29 | + } |
15 | 30 | if(depth == 0) {
|
| 31 | + printf(" label=\"Total threads: %d\\nTotal processes: %d\";\n", shared_data->total_threads, shared_data->total_processes); |
16 | 32 | printf("}\n");
|
17 | 33 | }
|
| 34 | + if(munmap(shared_data, sizeof(struct shared_data)) == -1) { |
| 35 | + perror("munmap"); |
| 36 | + } |
18 | 37 | }
|
19 | 38 |
|
20 |
| -pid_t frk(void) { |
21 |
| - if(!initialized) { |
22 |
| - printf("digraph process_tree {\n"); |
23 |
| - printf(" %d [label=\"root\"];\n", getpid()); |
24 |
| - atexit(close_graph); |
25 |
| - initialized = true; |
| 39 | +static void initialize(void) { |
| 40 | + if(initialized) { |
| 41 | + return; |
| 42 | + } |
| 43 | + shared_data = mmap(NULL, sizeof(struct shared_data), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); |
| 44 | + if(shared_data == MAP_FAILED) { |
| 45 | + perror("mmap"); |
| 46 | + exit(1); |
26 | 47 | }
|
| 48 | + shared_data->total_threads = 0; |
| 49 | + shared_data->total_processes = 1; |
| 50 | + printf("digraph process_tree {\n"); |
| 51 | + printf(" %d [label=\"root\"];\n", getpid()); |
| 52 | + atexit(close_graph); |
| 53 | + initialized = true; |
| 54 | +} |
| 55 | + |
| 56 | +pid_t frk(void) { |
| 57 | + initialize(); |
27 | 58 | fflush(stdout);
|
28 | 59 | pid_t child = fork();
|
29 | 60 | if(child != 0) {
|
30 | 61 | printf(" %d -> %d;\n", getpid(), child);
|
31 | 62 | printf(" %d [label=\"lvl %d\"];\n", child, depth + 1);
|
32 | 63 | } else {
|
33 | 64 | depth++;
|
| 65 | + thread_nr = 0; |
| 66 | + shared_data->total_processes++; |
34 | 67 | }
|
35 | 68 | return child;
|
36 | 69 | }
|
| 70 | + |
| 71 | +void thread_create(void) { |
| 72 | + initialize(); |
| 73 | + thread_nr++; |
| 74 | + shared_data->total_threads++; |
| 75 | +} |
0 commit comments