diff mbox series

[3/3] libselinux: use a static match_data if single threaded

Message ID 20230123014047.84911-4-carenas@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series improve performance of pcre matches | expand

Commit Message

Carlo Marcelo Arenas Belón Jan. 23, 2023, 1:40 a.m. UTC
A previous patch reimplemented a single threaded fallback while keeping
the memory usage low as was done originally by the workaround, but the
resulting code is too slow.

To improve performance, while keeping memory in check, use instead a
static match_data that gets reused for all queries and let its contents
(including the heapframes) leak.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
---
 libselinux/src/regex.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/libselinux/src/regex.c b/libselinux/src/regex.c
index 54f24026..a6b44023 100644
--- a/libselinux/src/regex.c
+++ b/libselinux/src/regex.c
@@ -220,7 +220,8 @@  void regex_data_free(struct regex_data *regex)
 int regex_match(struct regex_data *regex, char const *subject, int partial)
 {
 	int rc;
-	bool slow;
+	bool single_threaded;
+	static pcre2_match_data *static_match_data;
 	pcre2_match_data *match_data = NULL;
 
 	if (match_data_key_initialized > 0) {
@@ -238,10 +239,13 @@  int regex_match(struct regex_data *regex, char const *subject, int partial)
 			match_data = __selinux_getspecific(match_data_key);
 	}
 
-	slow = (match_data_key_initialized <= 0 || match_data == NULL);
-	if (slow) {
-		match_data = pcre2_match_data_create_from_pattern(regex->regex,
-									NULL);
+	single_threaded = (match_data_key_initialized <= 0 || !match_data);
+	if (single_threaded) {
+		if (!static_match_data && !match_data_initialized)
+			static_match_data = pcre2_match_data_create(1, NULL);
+
+		match_data_initialized = 1;
+		match_data = static_match_data;
 		if (!match_data)
 			return REGEX_ERROR;
 	}
@@ -250,9 +254,6 @@  int regex_match(struct regex_data *regex, char const *subject, int partial)
 	    regex->regex, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
 	    partial ? PCRE2_PARTIAL_SOFT : 0, match_data, NULL);
 
-	if (slow)
-		pcre2_match_data_free(match_data);
-
 	if (rc >= 0)
 		return REGEX_MATCH;
 	switch (rc) {