Skip to content

Multithreaded evaluator #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 146 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
6760b39
EvalState: Make the parse/eval caches thread-safe
edolstra Jan 4, 2024
d3854d1
LRUCache: Mark size() as const
edolstra Jan 4, 2024
945cd69
Sync: Add support for shared locks
edolstra Jan 4, 2024
5f3b1a3
WIP
edolstra Feb 4, 2024
9ddca98
WIP3
edolstra Mar 12, 2024
d133aca
WIP4
edolstra May 23, 2024
1a55754
Disable some blackhole tests for now
edolstra May 24, 2024
d623dfb
WIP working
edolstra May 28, 2024
a9e3594
Better hash
edolstra May 29, 2024
b63a132
Symbol table concurrency hack
edolstra May 29, 2024
76f822f
Hacks
edolstra May 29, 2024
6a85af7
Fix failures due to value reuse
edolstra May 31, 2024
6eafc52
Revive the Boehm GC alloc cache
edolstra May 31, 2024
f018a55
Make RegexCache thread-safe
edolstra May 31, 2024
ec8593d
Add some stats
edolstra Jun 3, 2024
105dea5
Cleanup
edolstra Jun 3, 2024
27fb652
Make EvalState::srcToStore thread-safe
edolstra Jun 4, 2024
d990974
PosixSourceAccessor: Use SharedSync
edolstra Jun 5, 2024
eba54f5
FileParseCache, FileEvalCache: Use read lock
edolstra Jun 5, 2024
a25a5b7
Add getOptional()
edolstra Jun 6, 2024
ca11328
EvalState: Add importResolutionCache
edolstra Jun 6, 2024
c2c01d8
Make fileEvalCache insertion more efficient
edolstra Jun 6, 2024
9b88021
Ensure that files are parsed/evaluated only once
edolstra Jun 6, 2024
708e0e8
Small optimization
edolstra Jun 6, 2024
cc38822
SymbolStr: Remove std::string conversion
edolstra Jun 6, 2024
424e01e
Use a contiguous arena for storing symbols
edolstra Jun 6, 2024
c663076
Executor: Randomize the work queue
edolstra Jun 6, 2024
adcc351
Provide std::hash<SourcePath>
edolstra Jun 6, 2024
3988faf
Provide std::hash<Symbol>
edolstra Jun 6, 2024
a70ec9e
Remove unused #include
edolstra Jun 6, 2024
0cd29fe
Split the symbol table into domains
edolstra Jun 6, 2024
0c87ead
Fix --disable-gc build
edolstra Jun 7, 2024
33f50ae
Don't use finishValue() for thunks
edolstra Jun 7, 2024
5e87cf4
Remove debug statement
edolstra Jun 7, 2024
400a670
Specify memory order
edolstra Jun 7, 2024
5c6eb1a
Split the PosixSourceAccessor lstat cache
edolstra Jun 7, 2024
3353f9a
nix search: Restore output
edolstra Jun 13, 2024
9b814c4
Make the max-call-depth check thread-local
edolstra Jun 13, 2024
fd5c32b
Move code
edolstra Jun 13, 2024
1bdf907
nix flake show: Make multi-threaded
edolstra Jun 14, 2024
3cc1319
Disable some failing tests for now
edolstra Jun 14, 2024
f6cbd6a
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jun 18, 2024
6103246
Cleanups
edolstra Jun 19, 2024
576a03e
Re-enable assertNoSymlinks()
edolstra Jun 19, 2024
52bd994
Formatting
edolstra Jun 19, 2024
b713591
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jun 19, 2024
fcbdc9f
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jul 3, 2024
997af66
Make the default GC_INITIAL_HEAP_SIZE a lot bigger
edolstra Jul 5, 2024
d3397d7
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jul 11, 2024
2b4c36f
Remove obsolete comment
edolstra Jul 11, 2024
d131a02
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jul 12, 2024
4482fe4
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Jul 26, 2024
8cf80c9
nix repl: Remove unnecessary call to evalString
edolstra Jul 26, 2024
67ff326
Remove FIXME
edolstra Jul 26, 2024
c8c9500
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Aug 5, 2024
dd44b26
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Aug 12, 2024
9102baf
Make AllowListSourceAccessor thread-safe
edolstra Aug 12, 2024
998a289
Make positionToDocComment thread-safe
edolstra Aug 12, 2024
5310b0f
callFunction(): Use correct environment in error messages
edolstra Aug 13, 2024
839aec2
callFunction(): Create the primop app chain safely
edolstra Aug 13, 2024
4f90786
Debug
edolstra Aug 13, 2024
6357885
Move perf counters into EvalState
edolstra Aug 13, 2024
4086c1c
Debug
edolstra Aug 13, 2024
a6d8217
Remove "SPURIOUS" message
edolstra Aug 13, 2024
ea4e981
Fix formatting
edolstra Aug 13, 2024
d36ea2e
Fix meson build
edolstra Aug 13, 2024
114d1a0
finishAll(): Propagate an arbitrary exception
edolstra Aug 14, 2024
f947b63
nix flake show: Make sure the visit() closure is still alive in case …
edolstra Aug 14, 2024
ceeb648
Introduce ValueType::nFailed
edolstra Aug 14, 2024
8b7d5b4
Make 'nix search --json' thread-safe
edolstra Aug 15, 2024
8020c0c
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Aug 22, 2024
fee4e0f
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Mar 11, 2025
8cf2af1
Formatting
edolstra Mar 11, 2025
d300e13
Use MAP_NORESERVE to avoid mmap failure on low-memory systems
edolstra Mar 11, 2025
8b374fd
Add eval-cores setting
edolstra Mar 12, 2025
c4ecaeb
Remove configure.ac
edolstra Mar 12, 2025
53356cf
Re-enable some tests
edolstra Mar 12, 2025
aa8025e
Tweak wording
edolstra Mar 12, 2025
250562c
Fix warning
edolstra Mar 12, 2025
50cf042
Fix UndefinedBehaviorSanitizer error passing a null Env
edolstra Mar 12, 2025
53f6b24
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Mar 17, 2025
e6caa9d
Merge remote-tracking branch 'origin/master' into multithreaded-eval
edolstra Mar 31, 2025
ce255bd
Merge remote-tracking branch 'detsys/multithreaded-eval' into sync-2.29
edolstra May 18, 2025
33b8a1e
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jun 3, 2025
825a2af
GitSourceAccessor: Make thread-safe
edolstra Jun 4, 2025
02eb215
nix flake check: Make multi-threaded
edolstra Jun 4, 2025
9d6bfdb
Prevent double copy of nixpkgs source tree
edolstra Jun 5, 2025
9ac8710
RemoteStore: Increase default maxConnections
edolstra Jun 5, 2025
ccf88cb
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jun 17, 2025
3746889
Move code out of header
edolstra Jun 18, 2025
fbb59f8
Move Executor into EvalState
edolstra Jun 18, 2025
509db3d
Make printValueAsJSON() multi-threaded
edolstra Jun 23, 2025
f649f50
Run flake-regressions with eval-cores = 24
edolstra Jun 23, 2025
5421f5c
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jun 23, 2025
0e4ed54
Fix macOS build
edolstra Jun 23, 2025
a66d268
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jun 30, 2025
dbc9423
nix flake prefetch-inputs: Add
edolstra Jun 24, 2025
9a52b2f
flake-regressions: Use prefetching
edolstra Jun 30, 2025
1626e65
Move FlakeCommand into a header, allow separate registration of subco…
edolstra Jun 26, 2025
7ec889d
Don't set $PARALLEL with eval-cores
edolstra Jun 30, 2025
59a2818
EvalState: Make the counters atomic
edolstra Jul 3, 2025
7156b63
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jul 3, 2025
a66991a
Restore mkBlackhole() for testing
edolstra Jul 3, 2025
08bf730
Re-enable some tests
edolstra Jul 3, 2025
aedaffd
Drop NIX_SHOW_THREAD_STATS
edolstra Jul 3, 2025
1b88cfc
Implement SymbolTable::dump()
edolstra Jul 3, 2025
2a245fc
Remove debug lines
edolstra Jul 3, 2025
529e500
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jul 10, 2025
a1c5533
SymbolTable: Use boost::concurrent_flat_set
edolstra Jul 10, 2025
47f8b6e
Update multithreaded eval to work with the 16-byte Value representation
edolstra Jul 11, 2025
88cd30d
Formatting
edolstra Jul 14, 2025
fcd49c0
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jul 14, 2025
0c09c4c
Remove debug line
edolstra Jul 14, 2025
e0779b6
Remove unnecessary diff
edolstra Jul 14, 2025
84cfa2b
PosixSourceAccessor: Use concurrent_flat_map
edolstra Jul 15, 2025
fe99dcf
Remove unused variable
edolstra Jul 15, 2025
d90ec7d
showHelp(): Simplify
edolstra Jul 15, 2025
a61c4ec
Remove unused Pending struct
edolstra Jul 15, 2025
914baff
Clean up CallDepth merge issue
edolstra Jul 15, 2025
0bcd256
Merge commit '47281531e' into multithreaded-eval-v2
edolstra Jul 23, 2025
69c848b
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jul 23, 2025
0c5bfeb
Merge remote-tracking branch 'detsys/detsys-main' into multithreaded-…
edolstra Jul 29, 2025
0a604eb
flake-regressions: Bypass the Nix daemon
edolstra Jul 29, 2025
9edfe78
Clean up reading thunks
edolstra Jul 29, 2025
1e8a3f3
usWaiting -> microsecondsWaiting
edolstra Jul 29, 2025
840970f
Use better casts
edolstra Jul 29, 2025
5dcdb1c
Remove unnecessary pureEval check
edolstra Jul 29, 2025
cb79524
Fix flake-regressions
edolstra Jul 29, 2025
ca5c411
Use flake-regressions main branch
edolstra Jul 29, 2025
d8a77d8
printError -> notice
edolstra Jul 30, 2025
9788d8c
Fix SymbolTable::dump()
edolstra Jul 30, 2025
6e908b5
Test
edolstra Jul 30, 2025
db9cc7b
Allow eval-cores to be set to 0 to use all cores
edolstra Jul 30, 2025
38e711b
Make Executor interruptible
edolstra Jul 31, 2025
e4b43ba
FutureVector: Ensure all items are going before throwing an exception
edolstra Jul 31, 2025
65189cf
Move setting GC_THREADS into eval-gc.hh
edolstra Aug 4, 2025
33dbefd
Optimize wakeup a bit
edolstra Aug 4, 2025
e904e34
Call GC_allow_register_threads() to enable parallel marking in Boehm GC
edolstra Aug 4, 2025
f0763d5
Move setting GC_THREADS into eval-gc.hh
edolstra Aug 4, 2025
8c53715
Apply a patch to boehmgc to increase the initial mark stack size
edolstra Aug 4, 2025
6a4cd24
Merge remote-tracking branch 'detsys/parallel-mark' into multithreade…
edolstra Aug 4, 2025
1f55bed
Fix eval-cores = 0
edolstra Aug 6, 2025
95a1a07
Less aggressive initial heap size
edolstra Aug 6, 2025
43d6737
Use -DINITIAL_MARK_STACK_SIZE
edolstra Aug 6, 2025
f78c858
Merge remote-tracking branch 'detsys/parallel-mark' into multithreade…
edolstra Aug 6, 2025
80c1139
Restore fixupBoehmStackPointer
edolstra Aug 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .github/workflows/build.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not related to this file, just left here so it can be marked resolved later)

This PR could also use some (very brief) docs on what things are currently affected by this -- reading the code and based on (spotty, tbf) recollection of past conversation, I believe this is currently limited to:

  • nix flake show
  • nix flake check

Did I miss any?

It would also be nice to add a list of commands that this does not currently affect (but will in the future, as we iron out issues and whatnot).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also speeds up

  • nix search
  • nix eval --json (used by flake-regressions)

Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ jobs:
nix_config:
- "lazy-trees = true"
- "lazy-trees = false"
- "eval-cores = 24"
glob:
- "[0-d]*"
- "[e-l]*"
Expand All @@ -151,23 +152,34 @@ jobs:
path: flake-regressions/tests
- uses: DeterminateSystems/determinate-nix-action@main
- uses: DeterminateSystems/flakehub-cache-action@main
- env:
PARALLEL: "-P 50%"
- name: Run flake regression tests
env:
#PARALLEL: ${{ !contains(matrix.nix_config, 'eval-cores') && '-P 50%' || '-P 1' }}
PARALLEL: '-P 1'
FLAKE_REGRESSION_GLOB: ${{ matrix.glob }}
NIX_CONFIG: ${{ matrix.nix_config }}
PREFETCH: "1"
run: |
set -x
echo "PARALLEL: $PARALLEL"
echo "NIX_CONFIG: $NIX_CONFIG"
if [ ! -z "${NSC_CACHE_PATH:-}" ]; then
mkdir -p "${NSC_CACHE_PATH}/nix/xdg-cache"
export XDG_CACHE_HOME="${NSC_CACHE_PATH}/nix/xdg-cache"
fi
nix build -L --out-link ./new-nix
export PATH=$(pwd)/new-nix/bin:$PATH
[[ $(type -p nix) = $(pwd)/new-nix/bin/nix ]]

nix config show lazy-trees
nix config show eval-cores
lscpu
nproc

if ! flake-regressions/eval-all.sh; then
echo "Some failed, trying again"
printf "\n\n\n\n\n\n\n\n"
flake-regressions/eval-all.sh
NIX_REMOTE=/tmp/nix flake-regressions/eval-all.sh
fi

manual:
Expand Down
16 changes: 13 additions & 3 deletions packaging/dependencies.nix
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,19 @@ scope: {
requiredSystemFeatures = [ ];
};

boehmgc = pkgs.boehmgc.override {
enableLargeConfig = true;
};
boehmgc =
(pkgs.boehmgc.override {
enableLargeConfig = true;
}).overrideAttrs
(attrs: {
# Increase the initial mark stack size to avoid stack
# overflows, since these inhibit parallel marking (see
# GC_mark_some()). To check whether the mark stack is too
# small, run Nix with GC_PRINT_STATS=1 and look for messages
# such as `Mark stack overflow`, `No room to copy back mark
# stack`, and `Grew mark stack to ... frames`.
NIX_CFLAGS_COMPILE = "-DINITIAL_MARK_STACK_SIZE=1048576";
});

# TODO Hack until https://github.com/NixOS/nixpkgs/issues/45462 is fixed.
boost =
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr-c/nix_api_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ ValueType nix_get_type(nix_c_context * context, const nix_value * value)
switch (v.type()) {
case nThunk:
return NIX_TYPE_THUNK;
case nFailed:
return NIX_TYPE_FAILED;
case nInt:
return NIX_TYPE_INT;
case nFloat:
Expand Down
3 changes: 2 additions & 1 deletion src/libexpr-c/nix_api_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ typedef enum {
NIX_TYPE_ATTRS,
NIX_TYPE_LIST,
NIX_TYPE_FUNCTION,
NIX_TYPE_EXTERNAL
NIX_TYPE_EXTERNAL,
NIX_TYPE_FAILED,
} ValueType;

// forward declarations
Expand Down
7 changes: 4 additions & 3 deletions src/libexpr-tests/value/print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ using namespace testing;
struct ValuePrintingTests : LibExprTest
{
template<class... A>
void test(Value v, std::string_view expected, A... args)
void test(Value & v, std::string_view expected, A... args)
{
std::stringstream out;
v.print(state, out, args...);
Expand Down Expand Up @@ -625,10 +625,11 @@ TEST_F(ValuePrintingTests, ansiColorsAttrsElided)
vThree.mkInt(3);

builder.insert(state.symbols.create("three"), &vThree);
vAttrs.mkAttrs(builder.finish());
Value vAttrs2;
vAttrs2.mkAttrs(builder.finish());

test(
vAttrs,
vAttrs2,
"{ one = " ANSI_CYAN "1" ANSI_NORMAL "; " ANSI_FAINT "«2 attributes elided»" ANSI_NORMAL " }",
PrintOptions{.ansiColors = true, .maxAttrs = 1});
}
Expand Down
1 change: 0 additions & 1 deletion src/libexpr-tests/value/value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ TEST_F(ValueTest, unsetValue)
{
Value unsetValue;
ASSERT_EQ(false, unsetValue.isValid());
ASSERT_EQ(nThunk, unsetValue.type(true));
ASSERT_DEATH(unsetValue.type(), "");
}

Expand Down
118 changes: 106 additions & 12 deletions src/libexpr/eval-gc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
# include <pthread_np.h>
# endif

# include <gc/gc.h>
# include <gc/gc_cpp.h>
# include <gc/gc_allocator.h>

# include <boost/coroutine2/coroutine.hpp>
Expand All @@ -35,6 +33,101 @@ static void * oomHandler(size_t requested)
throw std::bad_alloc();
}

static size_t getFreeMem()
{
/* On Linux, use the `MemAvailable` or `MemFree` fields from
/proc/cpuinfo. */
# ifdef __linux__
{
std::unordered_map<std::string, std::string> fields;
for (auto & line :
tokenizeString<std::vector<std::string>>(readFile(std::filesystem::path("/proc/meminfo")), "\n")) {
auto colon = line.find(':');
if (colon == line.npos)
continue;
fields.emplace(line.substr(0, colon), trim(line.substr(colon + 1)));
}

auto i = fields.find("MemAvailable");
if (i == fields.end())
i = fields.find("MemFree");
if (i != fields.end()) {
auto kb = tokenizeString<std::vector<std::string>>(i->second, " ");
if (kb.size() == 2 && kb[1] == "kB")
return string2Int<size_t>(kb[0]).value_or(0) * 1024;
}
}
# endif

/* On non-Linux systems, conservatively assume that 25% of memory is free. */
long pageSize = sysconf(_SC_PAGESIZE);
long pages = sysconf(_SC_PHYS_PAGES);
if (pageSize != -1)
return (pageSize * pages) / 4;
return 0;
}

/**
* When a thread goes into a coroutine, we lose its original sp until
* control flow returns to the thread. This causes Boehm GC to crash
* since it will scan memory between the coroutine's sp and the
* original stack base of the thread. Therefore, we detect when the
* current sp is outside of the original thread stack and push the
* entire thread stack instead, as an approximation.
*
* This is not optimal, because it causes the stack below sp to be
* scanned. However, we usually we don't have active coroutines during
* evaluation, so this is acceptable.
*
* Note that we don't scan coroutine stacks. It's currently assumed
* that we don't have GC roots in coroutines.
*/
void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
{
void *& sp = *sp_ptr;
auto pthread_id = reinterpret_cast<pthread_t>(_pthread_id);
size_t osStackSize;
// The low address of the stack, which grows down.
void * osStackLimit;

# ifdef __APPLE__
osStackSize = pthread_get_stacksize_np(pthread_id);
osStackLimit = pthread_get_stackaddr_np(pthread_id);
# else
pthread_attr_t pattr;
if (pthread_attr_init(&pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
}
# ifdef HAVE_PTHREAD_GETATTR_NP
if (pthread_getattr_np(pthread_id, &pattr)) {
throw Error("fixupBoehmStackPointer: pthread_getattr_np failed");
}
# elif HAVE_PTHREAD_ATTR_GET_NP
if (!pthread_attr_init(&pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
}
if (!pthread_attr_get_np(pthread_id, &pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_get_np failed");
}
# else
# error "Need one of `pthread_attr_get_np` or `pthread_getattr_np`"
# endif
if (pthread_attr_getstack(&pattr, &osStackLimit, &osStackSize)) {
throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed");
}
if (pthread_attr_destroy(&pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed");
}
# endif

void * osStackBase = (char *) osStackLimit + osStackSize;
// NOTE: We assume the stack grows down, as it does on all architectures we support.
// Architectures that grow the stack up are rare.
if (sp >= osStackBase || sp < osStackLimit) { // sp is outside the os stack
sp = osStackLimit;
}
}

static inline void initGCReal()
{
/* Initialise the Boehm garbage collector. */
Expand All @@ -53,6 +146,9 @@ static inline void initGCReal()

GC_INIT();

/* Enable parallel marking. */
GC_allow_register_threads();

/* Register valid displacements in case we are using alignment niches
for storing the type information. This way tagged pointers are considered
to be valid, even when they are not aligned. */
Expand All @@ -62,8 +158,11 @@ static inline void initGCReal()

GC_set_oom_fn(oomHandler);

/* Set the initial heap size to something fairly big (25% of
physical RAM, up to a maximum of 384 MiB) so that in most cases
GC_set_sp_corrector(&fixupBoehmStackPointer);
assert(GC_get_sp_corrector());

/* Set the initial heap size to something fairly big (80% of
free RAM, up to a maximum of 4 GiB) so that in most cases
we don't need to garbage collect at all. (Collection has a
fairly significant overhead.) The heap size can be overridden
through libgc's GC_INITIAL_HEAP_SIZE environment variable. We
Expand All @@ -74,15 +173,10 @@ static inline void initGCReal()
if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
size_t size = 32 * 1024 * 1024;
# if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
size_t maxSize = 384 * 1024 * 1024;
long pageSize = sysconf(_SC_PAGESIZE);
long pages = sysconf(_SC_PHYS_PAGES);
if (pageSize != -1)
size = (pageSize * pages) / 4; // 25% of RAM
if (size > maxSize)
size = maxSize;
size_t maxSize = 4ULL * 1024 * 1024 * 1024;
auto free = getFreeMem();
size = std::max(size, std::min((size_t) (free * 0.5), maxSize));
# endif
debug("setting initial heap size to %1% bytes", size);
GC_expand_hp(size);
}
}
Expand Down
Loading
Loading