blob: c88c6e9a054aa52bbd77362faf02899e042a24ac [file] [log] [blame]
/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#include "util.h"
static int compare(const void* a, const void* b) {
if (*(uint64_t*)a < *(uint64_t*)b) {
return -1;
}
if (*(uint64_t*)a > *(uint64_t*)b) {
return 1;
}
return 0;
}
static int addr_bits(void) {
#if defined(__i386__)
return 32;
#elif defined(__x86_64__)
return 47;
#elif defined(__aarch64__)
return 48;
#else
#error Define your architecture here
#endif
}
int check_range_available(uint64_t* ptrs, size_t num_ptrs, uint64_t map_size, uint64_t range_size) {
if (!num_ptrs) {
return 1;
}
qsort(ptrs, num_ptrs, sizeof(uint64_t), compare);
uint64_t last = 0;
for (size_t i = 0; i < num_ptrs; ++i) {
if (ptrs[i] - last >= range_size) {
return 1;
}
last = ptrs[i] + map_size;
}
uint64_t addr_max = ((uint64_t)1) << addr_bits();
if (addr_max - last >= range_size) {
return 1;
}
return 0;
}
int main(void) {
int i;
if (sizeof(void*) == 4) {
for (i = 0; i < 10; ++i) {
void* p = mmap(NULL, 512*1024*1024, PROT_NONE,
MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) {
test_assert(errno == ENOMEM);
break;
}
}
} else {
uint64_t ptrs[1024];
uint64_t map_size = ((uint64_t)512)*1024*1024*1024;
for (i = 0; i < 1024; ++i) {
void* p = mmap(NULL, map_size, PROT_NONE,
MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) {
test_assert(errno == ENOMEM);
break;
}
ptrs[i] = (uintptr_t)p;
}
test_assert(check_range_available(ptrs, i, map_size,
((uint64_t)4)*1024*1024*1024*1024));
}
atomic_puts("EXIT-SUCCESS");
return 0;
}