xref: /aosp_15_r20/system/extras/alloc-stress/mem-pressure.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker #include <errno.h>
2*288bf522SAndroid Build Coastguard Worker #include <fcntl.h>
3*288bf522SAndroid Build Coastguard Worker #include <getopt.h>
4*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
5*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
6*288bf522SAndroid Build Coastguard Worker #include <string.h>
7*288bf522SAndroid Build Coastguard Worker #include <sys/mman.h>
8*288bf522SAndroid Build Coastguard Worker #include <sys/wait.h>
9*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
10*288bf522SAndroid Build Coastguard Worker 
alloc_set(size_t size)11*288bf522SAndroid Build Coastguard Worker void* alloc_set(size_t size) {
12*288bf522SAndroid Build Coastguard Worker     void* addr = NULL;
13*288bf522SAndroid Build Coastguard Worker 
14*288bf522SAndroid Build Coastguard Worker     addr = malloc(size);
15*288bf522SAndroid Build Coastguard Worker     if (!addr) {
16*288bf522SAndroid Build Coastguard Worker         printf("Allocating %zd MB failed\n", size / 1024 / 1024);
17*288bf522SAndroid Build Coastguard Worker     } else {
18*288bf522SAndroid Build Coastguard Worker         memset(addr, 0, size);
19*288bf522SAndroid Build Coastguard Worker     }
20*288bf522SAndroid Build Coastguard Worker     return addr;
21*288bf522SAndroid Build Coastguard Worker }
22*288bf522SAndroid Build Coastguard Worker 
add_pressure(size_t * shared,size_t size,size_t step_size,size_t duration,const char * oom_score)23*288bf522SAndroid Build Coastguard Worker void add_pressure(size_t* shared, size_t size, size_t step_size, size_t duration,
24*288bf522SAndroid Build Coastguard Worker                   const char* oom_score) {
25*288bf522SAndroid Build Coastguard Worker     int fd, ret;
26*288bf522SAndroid Build Coastguard Worker 
27*288bf522SAndroid Build Coastguard Worker     fd = open("/proc/self/oom_score_adj", O_WRONLY);
28*288bf522SAndroid Build Coastguard Worker     ret = write(fd, oom_score, strlen(oom_score));
29*288bf522SAndroid Build Coastguard Worker     if (ret < 0) {
30*288bf522SAndroid Build Coastguard Worker         printf("Writing oom_score_adj failed with err %s\n", strerror(errno));
31*288bf522SAndroid Build Coastguard Worker     }
32*288bf522SAndroid Build Coastguard Worker     close(fd);
33*288bf522SAndroid Build Coastguard Worker 
34*288bf522SAndroid Build Coastguard Worker     if (alloc_set(size)) {
35*288bf522SAndroid Build Coastguard Worker         *shared = size;
36*288bf522SAndroid Build Coastguard Worker     }
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker     while (alloc_set(step_size)) {
39*288bf522SAndroid Build Coastguard Worker         size += step_size;
40*288bf522SAndroid Build Coastguard Worker         *shared = size;
41*288bf522SAndroid Build Coastguard Worker         usleep(duration);
42*288bf522SAndroid Build Coastguard Worker     }
43*288bf522SAndroid Build Coastguard Worker }
44*288bf522SAndroid Build Coastguard Worker 
usage()45*288bf522SAndroid Build Coastguard Worker void usage() {
46*288bf522SAndroid Build Coastguard Worker     printf("Usage: [OPTIONS]\n\n"
47*288bf522SAndroid Build Coastguard Worker            "  -d N: Duration in microsecond to sleep between each allocation.\n"
48*288bf522SAndroid Build Coastguard Worker            "  -i N: Number of iterations to run the alloc process.\n"
49*288bf522SAndroid Build Coastguard Worker            "  -o N: The oom_score to set the child process to before alloc.\n"
50*288bf522SAndroid Build Coastguard Worker            "  -s N: Number of bytes to allocate in an alloc process loop.\n");
51*288bf522SAndroid Build Coastguard Worker }
52*288bf522SAndroid Build Coastguard Worker 
main(int argc,char * argv[])53*288bf522SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
54*288bf522SAndroid Build Coastguard Worker     pid_t pid;
55*288bf522SAndroid Build Coastguard Worker     size_t* shared;
56*288bf522SAndroid Build Coastguard Worker     int c, i = 0;
57*288bf522SAndroid Build Coastguard Worker 
58*288bf522SAndroid Build Coastguard Worker     size_t duration = 1000;
59*288bf522SAndroid Build Coastguard Worker     int iterations = 0;
60*288bf522SAndroid Build Coastguard Worker     const char* oom_score = "899";
61*288bf522SAndroid Build Coastguard Worker     size_t step_size = 2 * 1024 * 1024;  // 2 MB
62*288bf522SAndroid Build Coastguard Worker     size_t size = step_size;
63*288bf522SAndroid Build Coastguard Worker 
64*288bf522SAndroid Build Coastguard Worker     while ((c = getopt(argc, argv, "hi:d:o:s:")) != -1) {
65*288bf522SAndroid Build Coastguard Worker         switch (c) {
66*288bf522SAndroid Build Coastguard Worker             case 'i':
67*288bf522SAndroid Build Coastguard Worker                 iterations = atoi(optarg);
68*288bf522SAndroid Build Coastguard Worker                 break;
69*288bf522SAndroid Build Coastguard Worker             case 'd':
70*288bf522SAndroid Build Coastguard Worker                 duration = atoi(optarg);
71*288bf522SAndroid Build Coastguard Worker                 break;
72*288bf522SAndroid Build Coastguard Worker             case 'o':
73*288bf522SAndroid Build Coastguard Worker                 oom_score = optarg;
74*288bf522SAndroid Build Coastguard Worker                 break;
75*288bf522SAndroid Build Coastguard Worker             case 's':
76*288bf522SAndroid Build Coastguard Worker                 step_size = atoi(optarg);
77*288bf522SAndroid Build Coastguard Worker                 break;
78*288bf522SAndroid Build Coastguard Worker             case 'h':
79*288bf522SAndroid Build Coastguard Worker                 usage();
80*288bf522SAndroid Build Coastguard Worker                 abort();
81*288bf522SAndroid Build Coastguard Worker             default:
82*288bf522SAndroid Build Coastguard Worker                 abort();
83*288bf522SAndroid Build Coastguard Worker         }
84*288bf522SAndroid Build Coastguard Worker     }
85*288bf522SAndroid Build Coastguard Worker 
86*288bf522SAndroid Build Coastguard Worker     shared = (size_t*)mmap(NULL, sizeof(size_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED,
87*288bf522SAndroid Build Coastguard Worker                            0, 0);
88*288bf522SAndroid Build Coastguard Worker 
89*288bf522SAndroid Build Coastguard Worker     while (iterations == 0 || i < iterations) {
90*288bf522SAndroid Build Coastguard Worker         *shared = 0;
91*288bf522SAndroid Build Coastguard Worker         pid = fork();
92*288bf522SAndroid Build Coastguard Worker         if (!pid) {
93*288bf522SAndroid Build Coastguard Worker             /* Child */
94*288bf522SAndroid Build Coastguard Worker             add_pressure(shared, size, step_size, duration, oom_score);
95*288bf522SAndroid Build Coastguard Worker             /* Shoud not get here */
96*288bf522SAndroid Build Coastguard Worker             exit(0);
97*288bf522SAndroid Build Coastguard Worker         } else {
98*288bf522SAndroid Build Coastguard Worker             wait(NULL);
99*288bf522SAndroid Build Coastguard Worker             printf("Child %d allocated %zd MB\n", i, *shared / 1024 / 1024);
100*288bf522SAndroid Build Coastguard Worker             size = *shared / 2;
101*288bf522SAndroid Build Coastguard Worker         }
102*288bf522SAndroid Build Coastguard Worker         i++;
103*288bf522SAndroid Build Coastguard Worker     }
104*288bf522SAndroid Build Coastguard Worker }
105