Branch libreoffice-24-8-3
[LibreOffice.git] / external / hunspell / clock-monotonic.patch.1
blobdd873f6c3908843d7b75ba3485a3ad5625884fb6
1 From 5737bdb3d7e5819528e33c360a73372e0e93a6be Mon Sep 17 00:00:00 2001
2 From: Noel Grandin <noel.grandin@collabora.co.uk>
3 Date: Fri, 3 Nov 2023 12:04:30 +0000
4 Subject: [PATCH] speed up hunspell inner loop
6 which calls into the kernel to get elapsed time, instead of using the
7 VDSO-based CLOCK_MONOTONIC (or at least, the C++ equivalent of that),
8 which is much faster
10 https://gerrit.libreoffice.org/c/core/+/158809
11 ---
12  src/hunspell/affixmgr.cxx | 43 +++++++++++++++++++++++----------------
13  1 file changed, 25 insertions(+), 18 deletions(-)
15 diff --git a/src/hunspell/affixmgr.cxx b/src/hunspell/affixmgr.cxx
16 index 2cad09f..a3c93cd 100644
17 --- a/src/hunspell/affixmgr.cxx
18 +++ b/src/hunspell/affixmgr.cxx
19 @@ -75,6 +75,7 @@
20  #include <ctime>
22  #include <algorithm>
23 +#include <chrono>
24  #include <memory>
25  #include <limits>
26  #include <string>
27 @@ -1590,17 +1591,20 @@ struct hentry* AffixMgr::compound_check(const std::string& word,
28    // add a time limit to handle possible
29    // combinatorical explosion of the overlapping words
31 -  HUNSPELL_THREAD_LOCAL clock_t timelimit;
32 +  HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start;
33 +  HUNSPELL_THREAD_LOCAL bool timelimit_exceeded;
35 +  // get the current time
36 +  std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now();
38    if (wordnum == 0) {
39 -      // get the start time, seeing as we're reusing this set to 0
40 -      // to flag timeout, use clock() + 1 to avoid start clock()
41 -      // of 0 as being a timeout
42 -      timelimit = clock() + 1;
43 -  }
44 -  else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) {
45 -      timelimit = 0;
46 +      // set the start time
47 +      clock_time_start = clock_now;
48 +      timelimit_exceeded = false;
49    }
50 +  else if (std::chrono::duration_cast<std::chrono::milliseconds>(clock_now - clock_time_start).count()
51 +            > TIMELIMIT * CLOCKS_PER_SEC * 1000)
52 +      timelimit_exceeded = true;
54    setcminmax(&cmin, &cmax, word.c_str(), len);
56 @@ -1626,7 +1630,7 @@ struct hentry* AffixMgr::compound_check(const std::string& word,
58        do {  // simplified checkcompoundpattern loop
60 -        if (timelimit == 0)
61 +        if (timelimit_exceeded)
62            return 0;
64          if (scpd > 0) {
65 @@ -2216,17 +2220,20 @@ int AffixMgr::compound_check_morph(const std::string& word,
66    // add a time limit to handle possible
67    // combinatorical explosion of the overlapping words
69 -  HUNSPELL_THREAD_LOCAL clock_t timelimit;
70 +  HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start;
71 +  HUNSPELL_THREAD_LOCAL bool timelimit_exceeded;
73 +  // get the current time
74 +  std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now();
76    if (wordnum == 0) {
77 -      // get the start time, seeing as we're reusing this set to 0
78 -      // to flag timeout, use clock() + 1 to avoid start clock()
79 -      // of 0 as being a timeout
80 -      timelimit = clock() + 1;
81 -  }
82 -  else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) {
83 -      timelimit = 0;
84 +      // set the start time
85 +      clock_time_start = clock_now;
86 +      timelimit_exceeded = false;
87    }
88 +  else if (std::chrono::duration_cast<std::chrono::milliseconds>(clock_now - clock_time_start).count()
89 +            > TIMELIMIT * CLOCKS_PER_SEC * 1000)
90 +      timelimit_exceeded = true;
92    setcminmax(&cmin, &cmax, word.c_str(), len);
94 @@ -2246,7 +2253,7 @@ int AffixMgr::compound_check_morph(const std::string& word,
96      do {  // onlycpdrule loop
98 -      if (timelimit == 0)
99 +      if (timelimit_exceeded)
100          return 0;
102        oldnumsyllable = numsyllable;
103 -- 
104 2.41.0