d2a2afcd6c5c19257f8ed2f746c3f94474f4ab78 braney Tue Sep 1 13:37:34 2026 -0700 hgTracks: let hg.conf set how big a step malloc takes, refs #38225 hgTracks loads tracks in parallel threads, and each thread grows its own memory pool in the 128 kB steps glibc uses by default. A heavy render asks the kernel to enlarge a pool about 133,000 times, work that does nothing for the reader. The new hg.conf setting mallocTopPad is a number of bytes. When it is set, cfgSetMallocTopPad() passes it to mallopt(M_TOP_PAD) before anything else in main() has a chance to allocate, so the heap grows in that size step instead. Absent or zero, glibc is left alone and nothing changes. Measured with the #38094 harness over eight sessions and two positions, at 32 MB: renders take 0.926 of the time they did, against a noise floor of 1.006. With the setting absent the same build measures 1.004, inside that noise floor. Through apache on a sandbox it measures 0.906. The cost is about 65 MB more resident memory on a heavy session and 8 to 20 MB on an ordinary view, where it also saves no measurable time; the saving and the cost are the same effect and appear together. The rendered image is byte identical either way. Off by default, so a server opts in. diff --git src/hg/hgTracks/mainMain.c src/hg/hgTracks/mainMain.c index 3a56e42cd40..fce837d8279 100644 --- src/hg/hgTracks/mainMain.c +++ src/hg/hgTracks/mainMain.c @@ -23,30 +23,34 @@ #include "versionInfo.h" #include "net.h" #include "search.h" #include "imageV2.h" #include "extTools.h" #include "botDelay.h" #include "hgConfig.h" #include #include boolean issueBotWarning; long enteredMainTime = 0; int main(int argc, char *argv[]) { +// First, before anything has a chance to allocate: read hg.conf and set how +// big a step the C library takes when it grows the heap. refs #38225 +cfgSetMallocTopPad(); + enteredMainTime = clock1000(); measureTime(NULL); // This is generic CGI setup code: Should be moved one day into a generic function // combined with the code cart.c:genericCgiSetup() ? cfgSetMaxMem(); // read hg.conf and set the maxMem if there cfgSetLogCgiVars(); // set logging of the CGI vars issueBotWarning = earlyBotCheck(enteredMainTime, "hgTracks", delayFraction, 0, 0, "html"); browserName = hBrowserName(); organization = "UCSC"; /* Push very early error handling - this is just * for the benefit of the cgiVarExists, which * somehow can't be moved effectively into doMiddle. */