... |
... |
@@ -585,6 +585,10 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len) |
585
|
585
|
}
|
586
|
586
|
#endif
|
587
|
587
|
|
|
588
|
+ const int MAX_ATTEMPTS = 8;
|
|
589
|
+ void *bad_allocs[MAX_ATTEMPTS] = {};
|
|
590
|
+ size_t bad_alloc_lens[MAX_ATTEMPTS] = {};
|
|
591
|
+
|
588
|
592
|
attempt = 0;
|
589
|
593
|
while (attempt < MAX_ATTEMPTS) {
|
590
|
594
|
*len &= ~MBLOCK_MASK;
|
... |
... |
@@ -611,18 +615,31 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len) |
611
|
615
|
} else if ((W_)at >= minimumAddress) {
|
612
|
616
|
// Success! We were given a block of memory starting above the 8 GB
|
613
|
617
|
// mark, which is what we were looking for.
|
614
|
|
-
|
615
|
618
|
break;
|
616
|
619
|
} else {
|
617
|
620
|
// We got addressing space but it wasn't above the 8GB mark.
|
618
|
|
- // Try again.
|
619
|
|
- if (munmap(at, *len) < 0) {
|
620
|
|
- sysErrorBelch("unable to release reserved heap");
|
|
621
|
+ // Free any portion *above* 8GB and hang on to the rest to increase
|
|
622
|
+ // the likelihood that we get a suitable allocation next iteration.
|
|
623
|
+ uintptr_t end = (W_) at + *len;
|
|
624
|
+ bad_allocs[attempt] = at;
|
|
625
|
+ if (end > minimumAddress) {
|
|
626
|
+ if (munmap((void *) minimumAddress, end - minimumAddress) < 0) {
|
|
627
|
+ sysErrorBelch("unable to release high portion of low memory reservation");
|
|
628
|
+ }
|
|
629
|
+ bad_alloc_lens[attempt] = minimumAddress - (W_) at;
|
|
630
|
+ } else {
|
|
631
|
+ bad_alloc_lens[attempt] = *len;
|
621
|
632
|
}
|
622
|
633
|
}
|
623
|
634
|
attempt++;
|
624
|
635
|
}
|
625
|
636
|
|
|
637
|
+ for (int i=0; i < MAX_ATTEMPTS; i++) {
|
|
638
|
+ if (bad_allocs[i] != NULL && munmap(bad_allocs[i], bad_alloc_lens[i]) < 0) {
|
|
639
|
+ sysErrorBelch("unable to release reserved heap");
|
|
640
|
+ }
|
|
641
|
+ }
|
|
642
|
+
|
626
|
643
|
if (at == NULL) {
|
627
|
644
|
sysErrorBelch("failed to reserve heap memory");
|
628
|
645
|
}
|