From 8e5174c1b9531e8e9c457c2b976cf2c929825e73 Mon Sep 17 00:00:00 2001 From: Michalis Spyrou Date: Tue, 4 Dec 2018 11:43:23 +0000 Subject: COMPMID-1817 Replace std::regex with POSIX C regex in runtime Change-Id: I6066cfc8c1bc16e212171cc9eb4bd6a3ab003485 Reviewed-on: https://review.mlplatform.org/318 Tested-by: Arm Jenkins Reviewed-by: Georgios Pinitas Reviewed-by: Anthony Barbier --- src/runtime/CPUUtils.cpp | 85 +++++++++++++++++++++++++++++++++++------------- src/runtime/MEMUtils.cpp | 44 +++++++++---------------- 2 files changed, 79 insertions(+), 50 deletions(-) (limited to 'src/runtime') diff --git a/src/runtime/CPUUtils.cpp b/src/runtime/CPUUtils.cpp index ac19d089da..6505964a1b 100644 --- a/src/runtime/CPUUtils.cpp +++ b/src/runtime/CPUUtils.cpp @@ -39,7 +39,8 @@ #include #ifndef BARE_METAL -#include +/* C++ std::regex takes up a lot of space in the standalone builds */ +#include #include #endif /* BARE_METAL */ @@ -172,12 +173,27 @@ void populate_models_cpuid(std::vector &cpusv) void populate_models_cpuinfo(std::vector &cpusv) { + regex_t proc_regex; + regex_t imp_regex; + regex_t var_regex; + regex_t part_regex; + regex_t rev_regex; + + memset(&proc_regex, 0, sizeof(regex_t)); + memset(&imp_regex, 0, sizeof(regex_t)); + memset(&var_regex, 0, sizeof(regex_t)); + memset(&part_regex, 0, sizeof(regex_t)); + memset(&rev_regex, 0, sizeof(regex_t)); + + int ret_status = 0; // If "long-form" cpuinfo is present, parse that to populate models. - std::regex proc_regex(R"(^processor.*(\d+)$)"); - std::regex imp_regex(R"(^CPU implementer.*0x(..)$)"); - std::regex var_regex(R"(^CPU variant.*0x(.)$)"); - std::regex part_regex(R"(^CPU part.*0x(...)$)"); - std::regex rev_regex(R"(^CPU revision.*(\d+)$)"); + ret_status |= regcomp(&proc_regex, R"(^processor.*([[:digit:]]+)$)", REG_EXTENDED); + ret_status |= regcomp(&imp_regex, R"(^CPU implementer.*0x(..)$)", REG_EXTENDED); + ret_status |= regcomp(&var_regex, R"(^CPU variant.*0x(.)$)", REG_EXTENDED); + ret_status |= regcomp(&part_regex, R"(^CPU part.*0x(...)$)", REG_EXTENDED); + ret_status |= regcomp(&rev_regex, R"(^CPU revision.*([[:digit:]]+)$)", REG_EXTENDED); + ARM_COMPUTE_UNUSED(ret_status); + ARM_COMPUTE_ERROR_ON_MSG(ret_status != 0, "Regex compilation failed."); std::ifstream file; file.open("/proc/cpuinfo", std::ios::in); @@ -190,11 +206,11 @@ void populate_models_cpuinfo(std::vector &cpusv) while(bool(getline(file, line))) { - std::smatch match; - - if(std::regex_match(line, match, proc_regex)) + regmatch_t match[2]; + ret_status = regexec(&proc_regex, line.c_str(), 2, match, 0); + if(ret_status == 0) { - std::string id = match[1]; + std::string id = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); int newcpu = support::cpp11::stoi(id, nullptr); if(curcpu >= 0 && midr == 0) @@ -214,32 +230,44 @@ void populate_models_cpuinfo(std::vector &cpusv) continue; } - if(std::regex_match(line, match, imp_regex)) + ret_status = regexec(&imp_regex, line.c_str(), 2, match, 0); + if(ret_status == 0) { - int impv = support::cpp11::stoi(match[1], nullptr, support::cpp11::NumericBase::BASE_16); + std::string subexp = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); + int impv = support::cpp11::stoi(subexp, nullptr, support::cpp11::NumericBase::BASE_16); midr |= (impv << 24); + continue; } - if(std::regex_match(line, match, var_regex)) + ret_status = regexec(&var_regex, line.c_str(), 2, match, 0); + if(ret_status == 0) { - int varv = support::cpp11::stoi(match[1], nullptr, support::cpp11::NumericBase::BASE_16); + std::string subexp = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); + int varv = support::cpp11::stoi(subexp, nullptr, support::cpp11::NumericBase::BASE_16); midr |= (varv << 20); + continue; } - if(std::regex_match(line, match, part_regex)) + ret_status = regexec(&part_regex, line.c_str(), 2, match, 0); + if(ret_status == 0) { - int partv = support::cpp11::stoi(match[1], nullptr, support::cpp11::NumericBase::BASE_16); + std::string subexp = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); + int partv = support::cpp11::stoi(subexp, nullptr, support::cpp11::NumericBase::BASE_16); midr |= (partv << 4); + continue; } - if(std::regex_match(line, match, rev_regex)) + ret_status = regexec(&rev_regex, line.c_str(), 2, match, 0); + if(ret_status == 0) { - int regv = support::cpp11::stoi(match[1], nullptr); + std::string subexp = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); + int regv = support::cpp11::stoi(subexp, nullptr); midr |= (regv); midr |= (0xf << 16); + continue; } } @@ -249,6 +277,13 @@ void populate_models_cpuinfo(std::vector &cpusv) cpusv[curcpu] = midr_to_model(midr); } } + + // Free allocated memory + regfree(&proc_regex); + regfree(&imp_regex); + regfree(&var_regex); + regfree(&part_regex); + regfree(&rev_regex); } int get_max_cpus() @@ -364,8 +399,11 @@ unsigned int get_threads_hint() std::map cpu_part_occurrence_map; // CPU part regex - std::regex cpu_part_rgx(R"(.*CPU part.+?(?=:).+?(?=\w+)(\w+).*)"); - std::smatch cpu_part_match; + regex_t cpu_part_rgx; + memset(&cpu_part_rgx, 0, sizeof(regex_t)); + int ret_status = regcomp(&cpu_part_rgx, R"(.*CPU part.+?\:[[:space:]]+([[:alnum:]]+).*)", REG_EXTENDED); + ARM_COMPUTE_UNUSED(ret_status); + ARM_COMPUTE_ERROR_ON_MSG(ret_status != 0, "Regex compilation failed."); // Read cpuinfo and get occurrence of each core std::ifstream cpuinfo; @@ -375,9 +413,11 @@ unsigned int get_threads_hint() std::string line; while(bool(getline(cpuinfo, line))) { - if(std::regex_search(line.cbegin(), line.cend(), cpu_part_match, cpu_part_rgx)) + regmatch_t match[2]; + ret_status = regexec(&cpu_part_rgx, line.c_str(), 2, match, 0); + if(ret_status == 0) { - std::string cpu_part = cpu_part_match[1]; + std::string cpu_part = line.substr(match[1].rm_so, (match[1].rm_eo - match[1].rm_so)); if(cpu_part_occurrence_map.find(cpu_part) != cpu_part_occurrence_map.end()) { cpu_part_occurrence_map[cpu_part]++; @@ -389,6 +429,7 @@ unsigned int get_threads_hint() } } } + regfree(&cpu_part_rgx); // Get min number of threads auto min_common_cores = std::min_element(cpu_part_occurrence_map.begin(), cpu_part_occurrence_map.end(), diff --git a/src/runtime/MEMUtils.cpp b/src/runtime/MEMUtils.cpp index be6a3b690d..5ae1c2abef 100644 --- a/src/runtime/MEMUtils.cpp +++ b/src/runtime/MEMUtils.cpp @@ -27,7 +27,7 @@ #ifndef BARE_METAL #include -#include +#include #include #endif // ifndef BARE_METAL @@ -43,45 +43,33 @@ void parse_mem_info(size_t &total, size_t &free, size_t &buffer) size_t memfree = 0; std::ifstream meminfo_f; meminfo_f.open("/proc/meminfo", std::ios::in); + if(meminfo_f.is_open()) { - std::stringstream str_stream; - str_stream << meminfo_f.rdbuf(); - const std::string str = str_stream.str(); -#ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED - try + std::string line; + while(bool(getline(meminfo_f, line))) { -#endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */ - std::smatch match; - if(std::regex_search(str, match, std::regex("MemTotal: (.*)kB")) && match.size() > 1) + std::istringstream iss(line); + std::vector tokens((std::istream_iterator(iss)), + std::istream_iterator()); + if(tokens[0] == "MemTotal:") { - const std::string result = match.str(1); - total = arm_compute::support::cpp11::stoul(result, nullptr); + total = arm_compute::support::cpp11::stoul(tokens[1], nullptr); } - if(std::regex_search(str, match, std::regex("MemFree: (.*)kB")) && match.size() > 1) + else if(tokens[0] == "MemFree:") { - const std::string result = match.str(1); - memfree = arm_compute::support::cpp11::stoul(result, nullptr); + memfree = arm_compute::support::cpp11::stoul(tokens[1], nullptr); } - if(std::regex_search(str, match, std::regex("Buffers: (.*)kB")) && match.size() > 1) + else if(tokens[0] == "Buffers:") { - const std::string result = match.str(1); - buffer = arm_compute::support::cpp11::stoul(result, nullptr); + buffer = arm_compute::support::cpp11::stoul(tokens[1], nullptr); } - if(std::regex_search(str, match, std::regex("Cached: (.*)kB")) && match.size() > 1) + else if(tokens[0] == "Cached:") { - const std::string result = match.str(1); - memcache = arm_compute::support::cpp11::stoul(result, nullptr); + memcache = arm_compute::support::cpp11::stoul(tokens[1], nullptr); } - free = memfree + (buffer + memcache); -#ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED - } - catch(std::regex_error &e) - { - // failed parsing /proc/meminfo - // return 0s on all fields } -#endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */ + free = memfree + (buffer + memcache); } #endif // ifndef BARE_METAL } -- cgit v1.2.1