1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci#include <regex.h> 17570af302Sopenharmony_ci#include "test-malloc-info-stats-print.h" 18570af302Sopenharmony_ci 19570af302Sopenharmony_ci#define THREAD_DATA_REGEX_LEN (MAX_TID_LEN + 43) 20570af302Sopenharmony_ci#define REGEX_NMATCH 1 21570af302Sopenharmony_ci 22570af302Sopenharmony_cistatic void stderr_stats_cb(void) 23570af302Sopenharmony_ci{ 24570af302Sopenharmony_ci malloc_stats_print(print_to_file, stderr, ""); 25570af302Sopenharmony_ci} 26570af302Sopenharmony_ci 27570af302Sopenharmony_cistatic int parse_amount(const char **s, long long *destination) 28570af302Sopenharmony_ci{ 29570af302Sopenharmony_ci char *end_ptr = NULL; 30570af302Sopenharmony_ci long long result = strtoll(*s, &end_ptr, 10); 31570af302Sopenharmony_ci if (end_ptr == *s) { 32570af302Sopenharmony_ci return 0; 33570af302Sopenharmony_ci } 34570af302Sopenharmony_ci *s = end_ptr; 35570af302Sopenharmony_ci if ((!isspace(*end_ptr) && *end_ptr != '\n' && *end_ptr != '\0') || result < 0) { 36570af302Sopenharmony_ci return 0; 37570af302Sopenharmony_ci } 38570af302Sopenharmony_ci *destination = result; 39570af302Sopenharmony_ci return 1; 40570af302Sopenharmony_ci} 41570af302Sopenharmony_ci 42570af302Sopenharmony_cistatic const char *find_thread_in_output(const char *output, const char *thread_id) 43570af302Sopenharmony_ci{ 44570af302Sopenharmony_ci char thread_data_regex_s[THREAD_DATA_REGEX_LEN + 1]; 45570af302Sopenharmony_ci snprintf(thread_data_regex_s, THREAD_DATA_REGEX_LEN, "^%s([[:space:]]+[[:digit:]]+){3}[[:space:]]*$", thread_id); 46570af302Sopenharmony_ci regex_t thread_data_regex; 47570af302Sopenharmony_ci if (regcomp(&thread_data_regex, thread_data_regex_s, REG_EXTENDED | REG_NEWLINE) != 0) { 48570af302Sopenharmony_ci t_error("Failed to compile regex %s", thread_data_regex_s); 49570af302Sopenharmony_ci return NULL; 50570af302Sopenharmony_ci } 51570af302Sopenharmony_ci 52570af302Sopenharmony_ci regmatch_t pmatch[REGEX_NMATCH]; 53570af302Sopenharmony_ci int match_result = regexec(&thread_data_regex, output, REGEX_NMATCH, pmatch, 0); 54570af302Sopenharmony_ci regfree(&thread_data_regex); 55570af302Sopenharmony_ci if (match_result != 0) { 56570af302Sopenharmony_ci return NULL; 57570af302Sopenharmony_ci } 58570af302Sopenharmony_ci return output + pmatch[0].rm_so; 59570af302Sopenharmony_ci} 60570af302Sopenharmony_ci 61570af302Sopenharmony_cistatic int populate_thread_stats(const char *output, const char *thread_id, malloc_thread_stats_t *stats) 62570af302Sopenharmony_ci{ 63570af302Sopenharmony_ci const char *thread_data_start = find_thread_in_output(output, thread_id); 64570af302Sopenharmony_ci if (thread_data_start == NULL) { 65570af302Sopenharmony_ci t_error("Failed to find thread id %s in output", thread_id); 66570af302Sopenharmony_ci return 0; 67570af302Sopenharmony_ci } 68570af302Sopenharmony_ci 69570af302Sopenharmony_ci thread_data_start += strlen(thread_id); 70570af302Sopenharmony_ci int result = 1; 71570af302Sopenharmony_ci result &= parse_amount(&thread_data_start, &stats->total_allocated_memory); 72570af302Sopenharmony_ci result &= parse_amount(&thread_data_start, &stats->total_mmapped_memory); 73570af302Sopenharmony_ci result &= parse_amount(&thread_data_start, &stats->mmapped_regions); 74570af302Sopenharmony_ci 75570af302Sopenharmony_ci return result; 76570af302Sopenharmony_ci} 77570af302Sopenharmony_ci 78570af302Sopenharmony_cistatic int populate_total_free_heap_space(const char *output, long long *total_free_heap_space) 79570af302Sopenharmony_ci{ 80570af302Sopenharmony_ci const char *free_heap_space_start = strstr(output, "total free heap space:"); 81570af302Sopenharmony_ci if (free_heap_space_start == NULL) { 82570af302Sopenharmony_ci return 0; 83570af302Sopenharmony_ci } 84570af302Sopenharmony_ci free_heap_space_start += strlen("total free heap space:"); 85570af302Sopenharmony_ci return parse_amount(&free_heap_space_start, total_free_heap_space); 86570af302Sopenharmony_ci} 87570af302Sopenharmony_ci 88570af302Sopenharmony_cistatic int is_thread_in_output(const char *output, const char *thread_id) 89570af302Sopenharmony_ci{ 90570af302Sopenharmony_ci return find_thread_in_output(output, thread_id) != NULL; 91570af302Sopenharmony_ci}