1 #include "test-stability.hpp"
13 #include <sys/sysinfo.h>
15 static size_t total_ram_kb; // /proc/meminfo returns in kB
16 static size_t total_ram_b () { return total_ram_kb * 1024; }
17 static size_t total_ram_mb () { return total_ram_kb / 1024; }
19 static void * do_mem (size_t to_alloc)
21 /* Allocate memory and pretend we're using it (so as to make it actually
22 * count to RSS use). The allocated amount stays constant. The memory is
23 * volatile to prevent smart compilers from optimizing stuff out. */
25 std::unique_ptr <volatile char []> ptr (new volatile char [to_alloc]);
26 for (size_t i = 0; i < to_alloc; i += 4096) // FIXME: 4096 -> page size
27 ptr[i] = 'a' + (i % ('z' - 'a'));
30 std::this_thread::sleep_for (std::chrono::seconds (1));
35 static void get_total_ram ()
37 std::ifstream meminfo ("/proc/meminfo");
39 std::string entry_name;
40 meminfo >> entry_name >> total_ram_kb;
42 if (entry_name != "MemTotal:")
43 throw std::runtime_error ("Unexpected format of /proc/meminfo");
45 std::cout << "Total RAM: " << total_ram_mb () << " MB" << std::endl;
48 unsigned long long operator "" _MB (unsigned long long n)
49 { return 1024 * 1024 * n; }
51 static void * mem_heavy_peak (void * arg)
52 { return do_mem (0.5f * total_ram_b ()); }
54 static void * mem_heavy_avg (void * arg)
55 { return do_mem (0.3f * total_ram_b ()); }
57 static void * mem_light (void * arg)
58 { return do_mem (25_MB); }
60 struct mem_handler : public dbus_signal_handler {
61 const std::string limitType;
62 static constexpr const char * const gtype = "(isdda{sv})";
64 mem_handler (const char * lt) : limitType (lt) { }
66 bool match (const gchar * objpath, const gchar * iface, GVariant * parameters) const override {
67 if ("/Org/Tizen/StabilityMonitor/tsm_mem"s != objpath
68 || "org.tizen.abnormality.mem.relative"s != iface
69 || !g_variant_is_of_type (parameters, G_VARIANT_TYPE(gtype)))
72 const char * paramType = nullptr;
74 g_variant_get (parameters, gtype, & pid, & paramType, nullptr, nullptr, nullptr);
75 return pid == getpid() && limitType == paramType;
77 } handler_avg ("avg"), handler_peak ("peak");
79 bool run_mem_test (thread_func_t * func, size_t test_time, dbus_signal_handler * handler)
80 { return run_test (func, 1, handler, test_time); }
82 int main (int argc, char ** argv)
86 const std::vector <std::pair <bool (*) (), std::string>> test_cases
88 /* Do a reasonable amount of memory (re)allocation.
89 * Expect no signal. */
90 return run_mem_test (mem_light, TEST_TIME_PEAK, & handler_peak);
91 } , "small allocation (25 MB + overhead), expecting no signal"
93 /* Allocate and keep lots of memory.
95 return ! run_mem_test (mem_heavy_peak, TEST_TIME_PEAK, & handler_peak);
96 } , "heavy allocation (50% of total (" + std::to_string(size_t (0.5 * total_ram_mb ())) + " MB) + overhead), expecting peak signal"
98 /* Allocate an amount of memory not high enough
99 * to trigger peak, but keep it long enough to
100 * trigger average. */
101 return ! run_mem_test (mem_heavy_avg, TEST_TIME_AVG, & handler_avg);
102 } , "medium allocation (30% of total (" + std::to_string(size_t (0.3 * total_ram_mb ())) + " MB) + overhead), expecting avg signal"
106 return standard_main (test_cases, argc, argv);