aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichalis Spyrou <michalis.spyrou@arm.com>2018-12-04 11:43:23 +0000
committerMichalis Spyrou <michalis.spyrou@arm.com>2018-12-20 17:32:41 +0000
commit8e5174c1b9531e8e9c457c2b976cf2c929825e73 (patch)
treea23a489b2c5c03754fabcf678224a7ea54c68b91
parent89124346020553068abc66a8f083193fbbdac03e (diff)
downloadComputeLibrary-8e5174c1b9531e8e9c457c2b976cf2c929825e73.tar.gz
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 <bsgcomp@arm.com> Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com> Reviewed-by: Anthony Barbier <Anthony.barbier@arm.com>
-rwxr-xr-xscripts/clang_tidy_rules.py1
-rw-r--r--src/runtime/CPUUtils.cpp85
-rw-r--r--src/runtime/MEMUtils.cpp44
3 files changed, 80 insertions, 50 deletions
diff --git a/scripts/clang_tidy_rules.py b/scripts/clang_tidy_rules.py
index b9d03be6e5..a7c5051638 100755
--- a/scripts/clang_tidy_rules.py
+++ b/scripts/clang_tidy_rules.py
@@ -94,6 +94,7 @@ def filter_clang_tidy_lines( lines ):
("NEGEMMLowpAssemblyMatrixMultiplyCore" in line and "constructor does not initialize these fields" in line) or
("CPUUtils.cpp" in line and "consider replacing 'unsigned long' with 'uint64'" in line) or
("CPUUtils.cpp" in line and "parameter 'cpusv' is unused" in line) or
+ ("CPUUtils.cpp" in line and "warning: uninitialized record type" in line) or
"3rdparty" in line):
print_context=False
continue
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 <unistd.h>
#ifndef BARE_METAL
-#include <regex>
+/* C++ std::regex takes up a lot of space in the standalone builds */
+#include <regex.h>
#include <thread>
#endif /* BARE_METAL */
@@ -172,12 +173,27 @@ void populate_models_cpuid(std::vector<CPUModel> &cpusv)
void populate_models_cpuinfo(std::vector<CPUModel> &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<CPUModel> &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<CPUModel> &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<CPUModel> &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<std::string, unsigned int> 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 <fstream>
-#include <regex>
+#include <iterator>
#include <sstream>
#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<std::string> tokens((std::istream_iterator<std::string>(iss)),
+ std::istream_iterator<std::string>());
+ 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
}