git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 10/25] grep/pcre2: move back to thread-only PCREv2 structures

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Feb 3, 2021, 03:27 UTC
Message-ID
<20210203032811.14979-11-avarab@gmail.com>
In-Reply-To
<20210203032811.14979-1-avarab@gmail.com>

Change the setup of the "pcre2_general_context" to happen per-thread in compile_pcre2_pattern() instead of in grep_init(), as happens with all the rest of the pcre2_* members of the grep_pat structure.

As noted in the preceding commit the approach 513f2b0bbd4 (grep: make PCRE2 aware of custom allocator, 2019-10-16) took to allocate the pcre2_general_context seems to have been initially based on a misunderstanding of how PCREv2 memory allocation works.

This approach of creating a global context is just added complexity for almost zero gain. On my system it's 24 bytes saved per-thread, for context PCREv2 will then go on to some kilobytes for its own thread-local state.

As noted in 6d423dd542f (grep: don't redundantly compile throwaway patterns under threading, 2017-05-25) the grep code is intentionally not trying to micro-optimize allocations by e.g. sharing some PCREv2 structures globally, while making others thread-local.

So let's remove this special case and make all of them thread-local for simplicity again.

See also the discussion in 94da9193a6 (grep: add support for PCRE v2, 2017-06-01) about thread safety, and Johannes's comments[1] to the effect that we should be doing what this patch is doing.

1. https://lore.kernel.org/git/nycvar.QRO.7.76.6.1908052120302.46@tvgsbejvaqbjf.bet/
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/grep.c |  1 -
 grep.c         | 41 +++++++++++++++--------------------------
 grep.h         |  3 ++-
 3 files changed, 17 insertions(+), 28 deletions(-)
diff --git a/builtin/grep.c b/builtin/grep.c
index 55d06c9513..c69fe99340 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1175,6 +1175,5 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		run_pager(&opt, prefix);
 	clear_pathspec(&pathspec);
 	free_grep_patterns(&opt);
-	grep_destroy();
 	return !hit;
 }
diff --git a/grep.c b/grep.c
index 0116ff5f09..2599f329cd 100644
--- a/grep.c
+++ b/grep.c
@@ -41,7 +41,6 @@ static struct grep_opt grep_defaults = {
 };
 
 #ifdef USE_LIBPCRE2
-static pcre2_general_context *pcre2_global_context;
 #define GREP_PCRE2_DEBUG_MALLOC 0
 
 static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data)
@@ -163,20 +162,9 @@ int grep_config(const char *var, const char *value, void *cb)
  * Initialize one instance of grep_opt and copy the
  * default values from the template we read the configuration
  * information in an earlier call to git_config(grep_config).
- *
- * If using PCRE, make sure that the library is configured
- * to use the same allocator as Git (e.g. nedmalloc on Windows).
- *
- * Any allocated memory needs to be released in grep_destroy().
  */
 void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
 {
-#if defined(USE_LIBPCRE2)
-	if (!pcre2_global_context)
-		pcre2_global_context = pcre2_general_context_create(
-					pcre2_malloc, pcre2_free, NULL);
-#endif
-
 	*opt = grep_defaults;
 
 	opt->repo = repo;
@@ -186,13 +174,6 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix
 	opt->header_tail = &opt->header_list;
 }
 
-void grep_destroy(void)
-{
-#ifdef USE_LIBPCRE2
-	pcre2_general_context_free(pcre2_global_context);
-#endif
-}
-
 static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
 {
 	/*
@@ -384,13 +365,20 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 	int patinforet;
 	size_t jitsizearg;
 
-	/* pcre2_global_context is initialized in grep_init */
+	/*
+	 * Call pcre2_general_context_create() before calling any
+	 * other pcre2_*(). It sets up our malloc()/free() functions
+	 * with which everything else is allocated.
+	 */
+	p->pcre2_general_context = pcre2_general_context_create(
+		pcre2_malloc, pcre2_free, NULL);
+	if (!p->pcre2_general_context)
+		die("Couldn't allocate PCRE2 general context");
+
 	if (opt->ignore_case) {
 		if (!opt->ignore_locale && has_non_ascii(p->pattern)) {
-			if (!pcre2_global_context)
-				BUG("pcre2_global_context uninitialized");
-			p->pcre2_tables = pcre2_maketables(pcre2_global_context);
-			p->pcre2_compile_context = pcre2_compile_context_create(pcre2_global_context);
+			p->pcre2_tables = pcre2_maketables(p->pcre2_general_context);
+			p->pcre2_compile_context = pcre2_compile_context_create(p->pcre2_general_context);
 			pcre2_set_character_tables(p->pcre2_compile_context,
 							p->pcre2_tables);
 		}
@@ -411,7 +399,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 					 p->pcre2_compile_context);
 
 	if (p->pcre2_pattern) {
-		p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, pcre2_global_context);
+		p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, p->pcre2_general_context);
 		if (!p->pcre2_match_data)
 			die("Couldn't allocate PCRE2 match data");
 	} else {
@@ -491,10 +479,11 @@ static void free_pcre2_pattern(struct grep_pat *p)
 	pcre2_code_free(p->pcre2_pattern);
 	pcre2_match_data_free(p->pcre2_match_data);
 #ifdef GIT_PCRE2_VERSION_10_34_OR_HIGHER
-	pcre2_maketables_free(pcre2_global_context, p->pcre2_tables);
+	pcre2_maketables_free(p->pcre2_general_context, p->pcre2_tables);
 #else
 	free((void *)p->pcre2_tables);
 #endif
+	pcre2_general_context_free(p->pcre2_general_context);
 }
 #else /* !USE_LIBPCRE2 */
 static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
diff --git a/grep.h b/grep.h
index 64666e9204..72f82b1e30 100644
--- a/grep.h
+++ b/grep.h
@@ -14,6 +14,7 @@
 typedef int pcre2_code;
 typedef int pcre2_match_data;
 typedef int pcre2_compile_context;
+typedef int pcre2_general_context;
 #endif
 #ifndef PCRE2_MATCH_INVALID_UTF
 /* PCRE2_MATCH_* dummy also with !USE_LIBPCRE2, for test-pcre2-config.c */
@@ -75,6 +76,7 @@ struct grep_pat {
 	pcre2_code *pcre2_pattern;
 	pcre2_match_data *pcre2_match_data;
 	pcre2_compile_context *pcre2_compile_context;
+	pcre2_general_context *pcre2_general_context;
 	const uint8_t *pcre2_tables;
 	uint32_t pcre2_jit_on;
 	unsigned fixed:1;
@@ -167,7 +169,6 @@ struct grep_opt {
 
 int grep_config(const char *var, const char *value, void *);
 void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
-void grep_destroy(void);
 void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
 
 void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
-- 
2.30.0.284.gd98b1dd5eaa7
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 11 of 99 in “grep: PCREv2 fixes, remove kwset.[ch]”
  1. 00/25 grep: PCREv2 fixes, remove kwset.[ch]Ævar Arnfjörð Bjarmason, Feb 3, 2021
  2. 01/25 grep/pcre2 tests: reword comments referring to kwsetÆvar Arnfjörð Bjarmason, Feb 3, 2021
  3. 03/25 grep/pcre2: drop needless assignment to NULLÆvar Arnfjörð Bjarmason, Feb 3, 2021
  4. 02/25 grep/pcre2: drop needless assignment + assert() on opt->pcre2Ævar Arnfjörð Bjarmason, Feb 3, 2021
  5. 04/25 grep/pcre2: correct reference to grep_init() in commentÆvar Arnfjörð Bjarmason, Feb 3, 2021
  6. 05/25 grep/pcre2: prepare to add debugging to pcre2_malloc()Ævar Arnfjörð Bjarmason, Feb 3, 2021
  7. 06/25 grep/pcre2: add GREP_PCRE2_DEBUG_MALLOC debug modeÆvar Arnfjörð Bjarmason, Feb 3, 2021
  8. 07/25 grep/pcre2: use compile-time PCREv2 version testÆvar Arnfjörð Bjarmason, Feb 3, 2021
  9. 08/25 grep/pcre2: use pcre2_maketables_free() functionÆvar Arnfjörð Bjarmason, Feb 3, 2021
  10. 09/25 grep/pcre2: actually make pcre2 use custom allocatorÆvar Arnfjörð Bjarmason, Feb 3, 2021
  11. 10/25 grep/pcre2: move back to thread-only PCREv2 structuresÆvar Arnfjörð Bjarmason, Feb 3, 2021
  12. 12/25 pickaxe tests: refactor to use test_commit --appendÆvar Arnfjörð Bjarmason, Feb 3, 2021
  13. 11/25 grep/pcre2: move definitions of pcre2_{malloc,free}Ævar Arnfjörð Bjarmason, Feb 3, 2021
  14. 13/25 pickaxe -S: support content with NULs under --pickaxe-regexÆvar Arnfjörð Bjarmason, Feb 3, 2021
  15. 14/25 pickaxe -S: remove redundant "sz" check in while-loopÆvar Arnfjörð Bjarmason, Feb 3, 2021
  16. René ScharfeFeb 4, 2021
  17. Junio C HamanoFeb 4, 2021
  18. Ævar Arnfjörð BjarmasonFeb 4, 2021
  19. 16/25 pickaxe tests: add test for diffgrep_consume() internalsÆvar Arnfjörð Bjarmason, Feb 3, 2021
  20. 18/25 perf: add performance test for pickaxeÆvar Arnfjörð Bjarmason, Feb 3, 2021
  21. 20/25 grep.h: make patmatch() a public functionÆvar Arnfjörð Bjarmason, Feb 3, 2021
  22. 23/25 xdiff-interface: allow early return from xdiff_emit_{line,hunk}_fnÆvar Arnfjörð Bjarmason, Feb 3, 2021
  23. 24/25 xdiff-interface: support early exit in xdiff_outf()Ævar Arnfjörð Bjarmason, Feb 3, 2021
  24. Junio C HamanoFeb 4, 2021
  25. 17/25 pickaxe tests: add test for "log -S" not being a regexÆvar Arnfjörð Bjarmason, Feb 3, 2021
  26. 19/25 pickaxe -G: set -U0 for diff generationÆvar Arnfjörð Bjarmason, Feb 3, 2021
  27. Ævar Arnfjörð BjarmasonFeb 3, 2021
  28. Junio C HamanoFeb 3, 2021
  29. 15/25 pickaxe/style: consolidate declarations and assignmentsÆvar Arnfjörð Bjarmason, Feb 3, 2021
  30. 21/25 pickaxe: use PCREv2 for -G and -SÆvar Arnfjörð Bjarmason, Feb 3, 2021
  31. Ævar Arnfjörð BjarmasonFeb 3, 2021
  32. Junio C HamanoFeb 4, 2021
  33. Junio C HamanoFeb 4, 2021
  34. 22/25 Remove unused kwset.[ch]Ævar Arnfjörð Bjarmason, Feb 3, 2021
  35. 25/25 pickaxe -G: terminate early on matching linesÆvar Arnfjörð Bjarmason, Feb 3, 2021
  36. Ævar Arnfjörð BjarmasonFeb 3, 2021
  37. 00/22 pickaxe: test and refactoring for follow-up changesÆvar Arnfjörð Bjarmason, Feb 16, 2021
  38. Junio C HamanoFeb 16, 2021
  39. Junio C HamanoFeb 17, 2021
  40. 00/22 pickaxe: test and refactoring for future PCRE backendÆvar Arnfjörð Bjarmason, Apr 12, 2021
  41. 01/22 grep/pcre2 tests: reword comments referring to kwsetÆvar Arnfjörð Bjarmason, Apr 12, 2021
  42. 02/22 pickaxe tests: refactor to use test_commit --append --printfÆvar Arnfjörð Bjarmason, Apr 12, 2021
  43. 03/22 pickaxe tests: add test for diffgrep_consume() internalsÆvar Arnfjörð Bjarmason, Apr 12, 2021
  44. 04/22 pickaxe tests: add test for "log -S" not being a regexÆvar Arnfjörð Bjarmason, Apr 12, 2021
  45. 05/22 pickaxe tests: test for -G, -S and --find-object incompatibilityÆvar Arnfjörð Bjarmason, Apr 12, 2021
  46. 06/22 pickaxe tests: add missing test for --no-pickaxe-regex being an errorÆvar Arnfjörð Bjarmason, Apr 12, 2021
  47. 07/22 pickaxe: die when -G and --pickaxe-regex are combinedÆvar Arnfjörð Bjarmason, Apr 12, 2021
  48. 08/22 pickaxe: die when --find-object and --pickaxe-all are combinedÆvar Arnfjörð Bjarmason, Apr 12, 2021
  49. 09/22 diff.h: move pickaxe fields together againÆvar Arnfjörð Bjarmason, Apr 12, 2021
  50. 10/22 pickaxe/style: consolidate declarations and assignmentsÆvar Arnfjörð Bjarmason, Apr 12, 2021
  51. 11/22 perf: add performance test for pickaxeÆvar Arnfjörð Bjarmason, Apr 12, 2021
  52. 12/22 pickaxe: refactor function selection in diffcore-pickaxe()Ævar Arnfjörð Bjarmason, Apr 12, 2021
  53. 13/22 pickaxe: assert that we must have a needle under -G or -SÆvar Arnfjörð Bjarmason, Apr 12, 2021
  54. 14/22 pickaxe -S: support content with NULs under --pickaxe-regexÆvar Arnfjörð Bjarmason, Apr 12, 2021
  55. 15/22 pickaxe: rename variables in has_changes() for brevityÆvar Arnfjörð Bjarmason, Apr 12, 2021
  56. 16/22 pickaxe -S: slightly optimize contains()Ævar Arnfjörð Bjarmason, Apr 12, 2021
  57. 17/22 xdiff-interface: prepare for allowing early returnÆvar Arnfjörð Bjarmason, Apr 12, 2021
  58. 18/22 xdiff-interface: allow early return from xdiff_emit_line_fnÆvar Arnfjörð Bjarmason, Apr 12, 2021
  59. 19/22 pickaxe -G: terminate early on matching linesÆvar Arnfjörð Bjarmason, Apr 12, 2021
  60. 20/22 pickaxe -G: don't special-case create/deleteÆvar Arnfjörð Bjarmason, Apr 12, 2021
  61. 21/22 xdiff users: use designated initializers for out_lineÆvar Arnfjörð Bjarmason, Apr 12, 2021
  62. 22/22 xdiff-interface: replace discard_hunk_line() with a flagÆvar Arnfjörð Bjarmason, Apr 12, 2021
  63. 01/22 grep/pcre2 tests: reword comments referring to kwsetÆvar Arnfjörð Bjarmason, Feb 16, 2021
  64. 02/22 test-lib-functions: document and test test_commit --no-tagÆvar Arnfjörð Bjarmason, Feb 16, 2021
  65. Junio C HamanoMar 30, 2021
  66. 03/22 test-lib-functions: reword "test_commit --append" docsÆvar Arnfjörð Bjarmason, Feb 16, 2021
  67. 04/22 test-lib functions: add --printf option to test_commitÆvar Arnfjörð Bjarmason, Feb 16, 2021
  68. Junio C HamanoMar 30, 2021
  69. Ævar Arnfjörð BjarmasonApr 12, 2021
  70. 05/22 pickaxe tests: refactor to use test_commit --append --printfÆvar Arnfjörð Bjarmason, Feb 16, 2021
  71. Junio C HamanoMar 30, 2021
  72. 06/22 pickaxe tests: add test for diffgrep_consume() internalsÆvar Arnfjörð Bjarmason, Feb 16, 2021
  73. 08/22 pickaxe tests: test for -G, -S and --find-object incompatibilityÆvar Arnfjörð Bjarmason, Feb 16, 2021
  74. Junio C HamanoMar 30, 2021
  75. 07/22 pickaxe tests: add test for "log -S" not being a regexÆvar Arnfjörð Bjarmason, Feb 16, 2021
  76. 09/22 pickaxe: die when -G and --pickaxe-regex are combinedÆvar Arnfjörð Bjarmason, Feb 16, 2021
  77. Junio C HamanoMar 30, 2021
  78. 11/22 diff.h: move pickaxe fields together againÆvar Arnfjörð Bjarmason, Feb 16, 2021
  79. 10/22 pickaxe: die when --find-object and --pickaxe-all are combinedÆvar Arnfjörð Bjarmason, Feb 16, 2021
  80. 14/22 pickaxe: refactor function selection in diffcore-pickaxe()Ævar Arnfjörð Bjarmason, Feb 16, 2021
  81. Junio C HamanoMar 30, 2021
  82. 12/22 pickaxe/style: consolidate declarations and assignmentsÆvar Arnfjörð Bjarmason, Feb 16, 2021
  83. 15/22 pickaxe: assert that we must have a needle under -G or -SÆvar Arnfjörð Bjarmason, Feb 16, 2021
  84. Junio C HamanoMar 30, 2021
  85. 17/22 pickaxe: rename variables in has_changes() for brevityÆvar Arnfjörð Bjarmason, Feb 16, 2021
  86. 13/22 perf: add performance test for pickaxeÆvar Arnfjörð Bjarmason, Feb 16, 2021
  87. 21/22 pickaxe -G: terminate early on matching linesÆvar Arnfjörð Bjarmason, Feb 16, 2021
  88. Junio C HamanoMar 31, 2021
  89. 16/22 pickaxe -S: support content with NULs under --pickaxe-regexÆvar Arnfjörð Bjarmason, Feb 16, 2021
  90. Junio C HamanoMar 30, 2021
  91. 22/22 pickaxe -G: don't special-case create/deleteÆvar Arnfjörð Bjarmason, Feb 16, 2021
  92. Junio C HamanoMar 31, 2021
  93. 18/22 pickaxe -S: slightly optimize contains()Ævar Arnfjörð Bjarmason, Feb 16, 2021
  94. Junio C HamanoMar 30, 2021
  95. 20/22 xdiff-interface: support early exit in xdiff_outf()Ævar Arnfjörð Bjarmason, Feb 16, 2021
  96. 19/22 xdiff-interface: allow early return from xdiff_emit_{line,hunk}_fnÆvar Arnfjörð Bjarmason, Feb 16, 2021
  97. Junio C HamanoMar 31, 2021
  98. Ævar Arnfjörð BjarmasonFeb 3, 2021
  99. Ævar Arnfjörð BjarmasonFeb 3, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.