I was doing some memory testing under fractional CPU allocations and it became painfully obvious that the repeat() function needs CHECK_FOR_INTERRUPTS().
I exchanged a few emails offlist with Tom about it, and (at the risk of putting words in his mouth) he agreed and felt it was a candidate for backpatching. Very small patch attached. Quick and dirty performance test: explain analyze SELECT repeat('A', 300000000); explain analyze SELECT repeat('A', 300000000); explain analyze SELECT repeat('A', 300000000); With an -O2 optimized build: Without CHECK_FOR_INTERRUPTS Planning Time: 1077.238 ms Execution Time: 0.016 ms Planning Time: 1080.381 ms Execution Time: 0.013 ms Planning Time: 1072.049 ms Execution Time: 0.013 ms With CHECK_FOR_INTERRUPTS Planning Time: 1078.703 ms Execution Time: 0.013 ms Planning Time: 1077.495 ms Execution Time: 0.013 ms Planning Time: 1076.793 ms Execution Time: 0.013 ms While discussing the above, Tom also wondered whether we should add unlikely() to the CHECK_FOR_INTERRUPTS() macro. Small patch for that also attached. I was not sure about the WIN32 stanza on that (to do it or not; if so, what about the UNBLOCKED_SIGNAL_QUEUE() test). I tested as above with unlikely() and did not see any discernible difference, but the added check might improve other code paths. Comments or objections? Thanks, Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index 0fdfee5..ecd8268 100644 *** a/src/backend/utils/adt/oracle_compat.c --- b/src/backend/utils/adt/oracle_compat.c *************** *** 19,25 **** #include "utils/builtins.h" #include "utils/formatting.h" #include "mb/pg_wchar.h" ! static text *dotrim(const char *string, int stringlen, const char *set, int setlen, --- 19,25 ---- #include "utils/builtins.h" #include "utils/formatting.h" #include "mb/pg_wchar.h" ! #include "miscadmin.h" static text *dotrim(const char *string, int stringlen, const char *set, int setlen, *************** repeat(PG_FUNCTION_ARGS) *** 1062,1067 **** --- 1062,1068 ---- { memcpy(cp, sp, slen); cp += slen; + CHECK_FOR_INTERRUPTS(); } PG_RETURN_TEXT_P(result);
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 61a24c2..0467a8e 100644 *** a/src/include/miscadmin.h --- b/src/include/miscadmin.h *************** extern void ProcessInterrupts(void); *** 98,104 **** #define CHECK_FOR_INTERRUPTS() \ do { \ ! if (InterruptPending) \ ProcessInterrupts(); \ } while(0) #else /* WIN32 */ --- 98,104 ---- #define CHECK_FOR_INTERRUPTS() \ do { \ ! if (unlikely(InterruptPending)) \ ProcessInterrupts(); \ } while(0) #else /* WIN32 */ *************** do { \ *** 107,113 **** do { \ if (UNBLOCKED_SIGNAL_QUEUE()) \ pgwin32_dispatch_queued_signals(); \ ! if (InterruptPending) \ ProcessInterrupts(); \ } while(0) #endif /* WIN32 */ --- 107,113 ---- do { \ if (UNBLOCKED_SIGNAL_QUEUE()) \ pgwin32_dispatch_queued_signals(); \ ! if (unlikely(InterruptPending)) \ ProcessInterrupts(); \ } while(0) #endif /* WIN32 */
signature.asc
Description: OpenPGP digital signature