summaryrefslogtreecommitdiff
path: root/alloc-stress
diff options
context:
space:
mode:
authorSherry Yang <sherryy@android.com>2017-08-25 19:05:50 -0700
committerSherry Yang <sherryy@android.com>2017-08-25 20:11:03 -0700
commit7277af87cc2a36661222c20ab7173c7933cd1a34 (patch)
tree81628518da27efcd0c91ca511a4d18e7ee247d9a /alloc-stress
parent14f2ee3581b867e70567693b4f3520a80ad2d9a3 (diff)
downloadextras-7277af87cc2a36661222c20ab7173c7933cd1a34.tar.gz
Memory pressure
Create continuous memory pressure by adjusting a child process's oom score and allocate in the child. When a child is killed by the low-memory-killer, fork another process and continues until the program is killed or certain number of iterations has reached. Bug: 63926541 Test: run mem-pressure on target Change-Id: Ic8ee60da7519c750de4bd690f26e31fa80c5cd49
Diffstat (limited to 'alloc-stress')
-rw-r--r--alloc-stress/Android.mk10
-rw-r--r--alloc-stress/mem-pressure.cpp107
2 files changed, 117 insertions, 0 deletions
diff --git a/alloc-stress/Android.mk b/alloc-stress/Android.mk
index ec19d798..ad46f262 100644
--- a/alloc-stress/Android.mk
+++ b/alloc-stress/Android.mk
@@ -12,3 +12,13 @@ LOCAL_SHARED_LIBRARIES := libhardware libcutils
LOCAL_SRC_FILES := \
alloc-stress.cpp
include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := mem-pressure
+LOCAL_CFLAGS += -g -Wall -Werror -Wno-missing-field-initializers -Wno-sign-compare
+ifneq ($(ENABLE_MEM_CGROUPS),)
+ LOCAL_CFLAGS += -DENABLE_MEM_CGROUPS
+endif
+LOCAL_SRC_FILES := \
+ mem-pressure.cpp
+include $(BUILD_EXECUTABLE)
diff --git a/alloc-stress/mem-pressure.cpp b/alloc-stress/mem-pressure.cpp
new file mode 100644
index 00000000..777015d3
--- /dev/null
+++ b/alloc-stress/mem-pressure.cpp
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <getopt.h>
+
+void *alloc_set(size_t size) {
+ void *addr = NULL;
+
+ addr = malloc(size);
+ if (!addr) {
+ printf("Allocating %zd MB failed\n", size / 1024 / 1024);
+ } else {
+ memset(addr, 0, size);
+ }
+ return addr;
+}
+
+void add_pressure(size_t *shared, size_t size, size_t step_size,
+ size_t duration, const char *oom_score) {
+ int fd, ret;
+
+ fd = open("/proc/self/oom_score_adj", O_WRONLY);
+ ret = write(fd, oom_score, strlen(oom_score));
+ if (ret < 0) {
+ printf("Writing oom_score_adj failed with err %s\n",
+ strerror(errno));
+ }
+ close(fd);
+
+ if (alloc_set(size)) {
+ *shared = size;
+ }
+
+ while (alloc_set(step_size)) {
+ size += step_size;
+ *shared = size;
+ usleep(duration);
+ }
+}
+
+void usage()
+{
+ printf("Usage: [OPTIONS]\n\n"
+ " -d N: Duration in microsecond to sleep between each allocation.\n"
+ " -i N: Number of iterations to run the alloc process.\n"
+ " -o N: The oom_score to set the child process to before alloc.\n"
+ " -s N: Number of bytes to allocate in an alloc process loop.\n"
+ );
+}
+
+int main(int argc, char *argv[])
+{
+ pid_t pid;
+ size_t *shared;
+ int c, i = 0;
+
+ size_t duration = 1000;
+ int iterations = 0;
+ const char *oom_score = "899";
+ size_t step_size = 2 * 1024 * 1024; // 2 MB
+ size_t size = step_size;
+
+ while ((c = getopt(argc, argv, "hi:d:o:s:")) != -1) {
+ switch (c)
+ {
+ case 'i':
+ iterations = atoi(optarg);
+ break;
+ case 'd':
+ duration = atoi(optarg);
+ break;
+ case 'o':
+ oom_score = optarg;
+ break;
+ case 's':
+ step_size = atoi(optarg);
+ break;
+ case 'h':
+ usage();
+ abort();
+ default:
+ abort();
+ }
+ }
+
+ shared = (size_t *)mmap(NULL, sizeof(size_t), PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_SHARED, 0, 0);
+
+ while (iterations == 0 || i < iterations) {
+ *shared = 0;
+ pid = fork();
+ if (!pid) {
+ /* Child */
+ add_pressure(shared, size, step_size, duration, oom_score);
+ /* Shoud not get here */
+ exit(0);
+ } else {
+ wait(NULL);
+ printf("Child %d allocated %zd MB\n", i,
+ *shared / 1024 / 1024);
+ size = *shared / 2;
+ }
+ i++;
+ }
+}