comparison src/search.c @ 29071:b90bca860b5a v8.2.5057

patch 8.2.5057: using gettimeofday() for timeout is very inefficient Commit: https://github.com/vim/vim/commit/6574577cacd393ab7591fc776ea060eebc939e55 Author: Paul Ollis <paul@cleversheep.org> Date: Sun Jun 5 16:55:54 2022 +0100 patch 8.2.5057: using gettimeofday() for timeout is very inefficient Problem: Using gettimeofday() for timeout is very inefficient. Solution: Set a platform dependent timer. (Paul Ollis, closes https://github.com/vim/vim/issues/10505)
author Bram Moolenaar <Bram@vim.org>
date Sun, 05 Jun 2022 18:00:08 +0200
parents 485619e7f836
children d1e263ecf634
comparison
equal deleted inserted replaced
29070:8bf8001ef6d5 29071:b90bca860b5a
656 int called_emsg_before = called_emsg; 656 int called_emsg_before = called_emsg;
657 #ifdef FEAT_SEARCH_EXTRA 657 #ifdef FEAT_SEARCH_EXTRA
658 int break_loop = FALSE; 658 int break_loop = FALSE;
659 #endif 659 #endif
660 linenr_T stop_lnum = 0; // stop after this line number when != 0 660 linenr_T stop_lnum = 0; // stop after this line number when != 0
661 #ifdef FEAT_RELTIME 661 int unused_timeout_flag = FALSE;
662 proftime_T *tm = NULL; // timeout limit or NULL 662 int *timed_out = &unused_timeout_flag; // set when timed out.
663 int *timed_out = NULL; // set when timed out or NULL
664 #endif
665
666 if (extra_arg != NULL)
667 {
668 stop_lnum = extra_arg->sa_stop_lnum;
669 #ifdef FEAT_RELTIME
670 tm = extra_arg->sa_tm;
671 timed_out = &extra_arg->sa_timed_out;
672 #endif
673 }
674 663
675 if (search_regcomp(pat, RE_SEARCH, pat_use, 664 if (search_regcomp(pat, RE_SEARCH, pat_use,
676 (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL) 665 (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL)
677 { 666 {
678 if ((options & SEARCH_MSG) && !rc_did_emsg) 667 if ((options & SEARCH_MSG) && !rc_did_emsg)
679 semsg(_(e_invalid_search_string_str), mr_pattern); 668 semsg(_(e_invalid_search_string_str), mr_pattern);
680 return FAIL; 669 return FAIL;
670 }
671
672 if (extra_arg != NULL)
673 {
674 stop_lnum = extra_arg->sa_stop_lnum;
675 #ifdef FEAT_RELTIME
676 if (extra_arg->sa_tm > 0)
677 {
678 init_regexp_timeout(extra_arg->sa_tm);
679 timed_out = &extra_arg->sa_timed_out;
680 }
681 #endif
681 } 682 }
682 683
683 /* 684 /*
684 * find the string 685 * find the string
685 */ 686 */
751 { 752 {
752 // Stop after checking "stop_lnum", if it's set. 753 // Stop after checking "stop_lnum", if it's set.
753 if (stop_lnum != 0 && (dir == FORWARD 754 if (stop_lnum != 0 && (dir == FORWARD
754 ? lnum > stop_lnum : lnum < stop_lnum)) 755 ? lnum > stop_lnum : lnum < stop_lnum))
755 break; 756 break;
756 #ifdef FEAT_RELTIME 757 // Stop after passing the time limit.
757 // Stop after passing the "tm" time limit. 758 if (*timed_out)
758 if (tm != NULL && profile_passed_limit(tm))
759 break; 759 break;
760 #endif
761 760
762 /* 761 /*
763 * Look for a match somewhere in line "lnum". 762 * Look for a match somewhere in line "lnum".
764 */ 763 */
765 col = at_first_line && (options & SEARCH_COL) ? pos->col 764 col = at_first_line && (options & SEARCH_COL) ? pos->col
766 : (colnr_T)0; 765 : (colnr_T)0;
767 nmatched = vim_regexec_multi(&regmatch, win, buf, 766 nmatched = vim_regexec_multi(&regmatch, win, buf,
768 lnum, col, 767 lnum, col, timed_out);
769 #ifdef FEAT_RELTIME
770 tm, timed_out
771 #else
772 NULL, NULL
773 #endif
774 );
775 // vim_regexec_multi() may clear "regprog" 768 // vim_regexec_multi() may clear "regprog"
776 if (regmatch.regprog == NULL) 769 if (regmatch.regprog == NULL)
777 break; 770 break;
778 // Abort searching on an error (e.g., out of stack). 771 // Abort searching on an error (e.g., out of stack).
779 if (called_emsg > called_emsg_before 772 if (called_emsg > called_emsg_before || *timed_out)
780 #ifdef FEAT_RELTIME
781 || (timed_out != NULL && *timed_out)
782 #endif
783 )
784 break; 773 break;
785 if (nmatched > 0) 774 if (nmatched > 0)
786 { 775 {
787 // match may actually be in another line when using \zs 776 // match may actually be in another line when using \zs
788 matchpos = regmatch.startpos[0]; 777 matchpos = regmatch.startpos[0];
861 if (matchcol == 0 && (options & SEARCH_START)) 850 if (matchcol == 0 && (options & SEARCH_START))
862 break; 851 break;
863 if (ptr[matchcol] == NUL 852 if (ptr[matchcol] == NUL
864 || (nmatched = vim_regexec_multi(&regmatch, 853 || (nmatched = vim_regexec_multi(&regmatch,
865 win, buf, lnum + matchpos.lnum, 854 win, buf, lnum + matchpos.lnum,
866 matchcol, 855 matchcol, timed_out)) == 0)
867 #ifdef FEAT_RELTIME
868 tm, timed_out
869 #else
870 NULL, NULL
871 #endif
872 )) == 0)
873 { 856 {
874 match_ok = FALSE; 857 match_ok = FALSE;
875 break; 858 break;
876 } 859 }
877 // vim_regexec_multi() may clear "regprog" 860 // vim_regexec_multi() may clear "regprog"
972 } 955 }
973 } 956 }
974 if (ptr[matchcol] == NUL 957 if (ptr[matchcol] == NUL
975 || (nmatched = vim_regexec_multi(&regmatch, 958 || (nmatched = vim_regexec_multi(&regmatch,
976 win, buf, lnum + matchpos.lnum, 959 win, buf, lnum + matchpos.lnum,
977 matchcol, 960 matchcol, timed_out)) == 0)
978 #ifdef FEAT_RELTIME
979 tm, timed_out
980 #else
981 NULL, NULL
982 #endif
983 )) == 0)
984 { 961 {
985 #ifdef FEAT_RELTIME
986 // If the search timed out, we did find a match 962 // If the search timed out, we did find a match
987 // but it might be the wrong one, so that's not 963 // but it might be the wrong one, so that's not
988 // OK. 964 // OK.
989 if (timed_out != NULL && *timed_out) 965 if (*timed_out)
990 match_ok = FALSE; 966 match_ok = FALSE;
991 #endif
992 break; 967 break;
993 } 968 }
994 // vim_regexec_multi() may clear "regprog" 969 // vim_regexec_multi() may clear "regprog"
995 if (regmatch.regprog == NULL) 970 if (regmatch.regprog == NULL)
996 break; 971 break;
1095 * Stop the search if wrapscan isn't set, "stop_lnum" is 1070 * Stop the search if wrapscan isn't set, "stop_lnum" is
1096 * specified, after an interrupt, after a match and after looping 1071 * specified, after an interrupt, after a match and after looping
1097 * twice. 1072 * twice.
1098 */ 1073 */
1099 if (!p_ws || stop_lnum != 0 || got_int 1074 if (!p_ws || stop_lnum != 0 || got_int
1100 || called_emsg > called_emsg_before 1075 || called_emsg > called_emsg_before || *timed_out
1101 #ifdef FEAT_RELTIME
1102 || (timed_out != NULL && *timed_out)
1103 #endif
1104 #ifdef FEAT_SEARCH_EXTRA 1076 #ifdef FEAT_SEARCH_EXTRA
1105 || break_loop 1077 || break_loop
1106 #endif 1078 #endif
1107 || found || loop) 1079 || found || loop)
1108 break; 1080 break;
1122 give_warning((char_u *)_(dir == BACKWARD 1094 give_warning((char_u *)_(dir == BACKWARD
1123 ? top_bot_msg : bot_top_msg), TRUE); 1095 ? top_bot_msg : bot_top_msg), TRUE);
1124 if (extra_arg != NULL) 1096 if (extra_arg != NULL)
1125 extra_arg->sa_wrapped = TRUE; 1097 extra_arg->sa_wrapped = TRUE;
1126 } 1098 }
1127 if (got_int || called_emsg > called_emsg_before 1099 if (got_int || called_emsg > called_emsg_before || *timed_out
1128 #ifdef FEAT_RELTIME
1129 || (timed_out != NULL && *timed_out)
1130 #endif
1131 #ifdef FEAT_SEARCH_EXTRA 1100 #ifdef FEAT_SEARCH_EXTRA
1132 || break_loop 1101 || break_loop
1133 #endif 1102 #endif
1134 ) 1103 )
1135 break; 1104 break;
1136 } 1105 }
1137 while (--count > 0 && found); // stop after count matches or no match 1106 while (--count > 0 && found); // stop after count matches or no match
1138 1107
1108 # ifdef FEAT_RELTIME
1109 disable_regexp_timeout();
1110 # endif
1139 vim_regfree(regmatch.regprog); 1111 vim_regfree(regmatch.regprog);
1140 1112
1141 if (!found) // did not find it 1113 if (!found) // did not find it
1142 { 1114 {
1143 if (got_int) 1115 if (got_int)
2913 // start and end are in the same position. 2885 // start and end are in the same position.
2914 do 2886 do
2915 { 2887 {
2916 regmatch.startpos[0].col++; 2888 regmatch.startpos[0].col++;
2917 nmatched = vim_regexec_multi(&regmatch, curwin, curbuf, 2889 nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
2918 pos.lnum, regmatch.startpos[0].col, NULL, NULL); 2890 pos.lnum, regmatch.startpos[0].col, NULL);
2919 if (nmatched != 0) 2891 if (nmatched != 0)
2920 break; 2892 break;
2921 } while (regmatch.regprog != NULL 2893 } while (regmatch.regprog != NULL
2922 && direction == FORWARD ? regmatch.startpos[0].col < pos.col 2894 && direction == FORWARD ? regmatch.startpos[0].col < pos.col
2923 : regmatch.startpos[0].col > pos.col); 2895 : regmatch.startpos[0].col > pos.col);