-
Notifications
You must be signed in to change notification settings - Fork 0
/
fork.c
68 lines (58 loc) · 2.01 KB
/
fork.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/* To run: gcc -march=native -o fork fork.c && ./fork && sleep 1 */
/* Notes on the fork() syscall:
* successive forks behave like a balanced binary tree
* conditional forks cut subtrees from said tree
* forked code continues execution from where it was forked (that is, program
* counter doesn't reset)
* a fork() call returns pid-of-child on parent, and 0 on child
* a getpid() call returns current process id
* a getppid() call returns parent process id
* a wait() call is necessary for the child process to not turn into a zombie
* and be adopted by PID1
* on multiple fork() calls, the number of 0 values can be a sign on the
* process origins. If c1 and c2 are 0, c3 is a value, then you're on the
* process created by c1, that is c2, which calls fork and stores that in c3
*
* the tree for the three successive unconditional fork() calls below is like
* so:
* -------- p ------------ 1st call to fork()
* / \
* ---- p c1 -------- 2nd call
* / \ / \
* -- p c2 c1 c2 ---- 3rd call
* / | / | | \ | \
* p c3 c2 c3 c1 c3 c2 c3 rest of the program
* 8 7 6 5 4 3 2 1 exec order with waits
*
* exec order without waits is not guaranteed, but logically it's inverse of
* the one with waits.
*/
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <wait.h>
typedef uint64_t u64;
typedef uint32_t u32;
// timing: rdtscp is a post-pentium opcode that returns the number of cpu cycles
// since a ref point in time.
inline u64 rdtsc(void) {
struct {u32 lo; u32 hi;} out;
asm volatile ("rdtscp": "=a"(out.lo), "=d"(out.hi));
return *(u64*)&out;
}
int main()
{
pid_t c1, c2, c3;
/* fork() && fork() || fork() */
/* fork() && (fork() || fork()) */
c1 = fork();
wait(NULL); // we have to wait so getppid doesn't return PID1
c2 = fork();
wait(NULL);
c3 = fork();
wait(NULL);
printf("cycle: %lu\t", rdtsc());
printf("| my PID: % 8d, my Parent: % 8d\t", getpid(), getppid());
printf("| values:: c1: % 8d, c2: % 8d, c3: % 8d\n", c1, c2, c3);
return 0;
}