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