[Linux] Port MallocBench
[WebKit-https.git] / PerformanceTests / MallocBench / MallocBench / Memory.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "Memory.h"
28 #include <iostream>
29 #include <stdlib.h>
30
31 #ifdef __APPLE__
32 #include <mach/mach.h>
33 #include <mach/task_info.h>
34 #else
35 #include <stdio.h>
36 #include <unistd.h>
37 #endif
38
39 Memory currentMemoryBytes()
40 {
41     Memory memory;
42
43 #ifdef __APPLE__
44     task_vm_info_data_t vm_info;
45     mach_msg_type_number_t vm_size = TASK_VM_INFO_COUNT;
46     if (KERN_SUCCESS != task_info(mach_task_self(), TASK_VM_INFO_PURGEABLE, (task_info_t)(&vm_info), &vm_size)) {
47         std::cout << "Failed to get mach task info" << std::endl;
48         exit(1);
49     }
50
51     memory.resident = vm_info.internal + vm_info.compressed - vm_info.purgeable_volatile_pmap;
52     memory.residentMax = vm_info.resident_size_peak;
53 #else
54     FILE* file = fopen("/proc/self/status", "r");
55
56     auto forEachLine = [] (FILE* file, auto functor) {
57         char* buffer = nullptr;
58         size_t size = 0;
59         while (getline(&buffer, &size, file) != -1) {
60             functor(buffer, size);
61             ::free(buffer); // Be careful. getline's memory allocation is done by system malloc.
62             buffer = nullptr;
63             size = 0;
64         }
65     };
66
67     unsigned long vmHWM = 0;
68     unsigned long vmRSS = 0;
69     unsigned long rssFile = 0;
70     unsigned long rssShmem = 0;
71     forEachLine(file, [&] (char* buffer, size_t) {
72         unsigned long sizeInKB = 0;
73         if (sscanf(buffer, "VmHWM: %lu kB", &sizeInKB) == 1)
74             vmHWM = sizeInKB * 1024;
75         else if (sscanf(buffer, "VmRSS: %lu kB", &sizeInKB) == 1)
76             vmRSS = sizeInKB * 1024;
77         else if (sscanf(buffer, "RssFile: %lu kB", &sizeInKB) == 1)
78             rssFile = sizeInKB * 1024;
79         else if (sscanf(buffer, "RssShmem: %lu kB", &sizeInKB) == 1)
80             rssShmem = sizeInKB * 1024;
81     });
82     fclose(file);
83     memory.resident = vmRSS - (rssFile + rssShmem);
84     memory.residentMax = vmHWM - (rssFile + rssShmem); // We do not have any way to get the peak of RSS of anonymous pages. Here, we subtract RSS of files and shmem to estimate the peak of RSS of anonymous pages.
85 #endif
86     return memory;
87 }