in source/hack_parallel/hack_parallel/heap/hh_shared.c [798:893]
static void define_globals(char* shared_mem_init) {
size_t page_size = getpagesize();
char* mem = shared_mem_init;
// Beginning of the shared memory
shared_mem = mem;
#ifdef MADV_DONTDUMP
// We are unlikely to get much useful information out of the shared heap in
// a core file. Moreover, it can be HUGE, and the extensive work done dumping
// it once for each CPU can mean that the user will reboot their machine
// before the much more useful stack gets dumped!
madvise(shared_mem, shared_mem_size, MADV_DONTDUMP);
#endif
/* BEGINNING OF THE SMALL OBJECTS PAGE
* We keep all the small objects in this page.
* They are on different cache lines because we modify them atomically.
*/
/* The pointer to the top of the heap.
* We will atomically increment *heap every time we want to allocate.
*/
heap = (char**)mem;
// The number of elements in the hashtable
assert(CACHE_LINE_SIZE >= sizeof(uint64_t));
hcounter = (uint64_t*)(mem + CACHE_LINE_SIZE);
// The number of elements in the deptable
assert(CACHE_LINE_SIZE >= sizeof(uint64_t));
dcounter = (uint64_t*)(mem + 2 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(uintptr_t));
counter = (uintptr_t*)(mem + 3 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(pid_t));
master_pid = (pid_t*)(mem + 4 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(size_t));
log_level = (size_t*)(mem + 5 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(size_t));
workers_should_exit = (size_t*)(mem + 6 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(size_t));
wasted_heap_size = (size_t*)(mem + 7 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(size_t));
allow_removes = (size_t*)(mem + 8 * CACHE_LINE_SIZE);
assert(CACHE_LINE_SIZE >= sizeof(size_t));
allow_dependency_table_reads = (size_t*)(mem + 9 * CACHE_LINE_SIZE);
mem += page_size;
// Just checking that the page is large enough.
assert(page_size > 10 * CACHE_LINE_SIZE + (int)sizeof(int));
/* File name we get in hh_load_dep_table_sqlite needs to be smaller than
* page_size - it should be since page_size is quite big for a string
*/
db_filename = (char*)mem;
mem += page_size;
hashtable_db_filename = (char*)mem;
mem += page_size;
/* END OF THE SMALL OBJECTS PAGE */
/* Global storage initialization */
global_storage = (value*)mem;
mem += global_size_b;
/* Dependencies */
deptbl = (deptbl_entry_t*)mem;
mem += dep_size_b;
deptbl_bindings = (uint64_t*)mem;
mem += bindings_size_b;
/* Hashtable */
hashtbl = (helt_t*)mem;
mem += hashtbl_size_b;
/* Heap */
heap_init = mem;
heap_max = heap_init + heap_size;
#ifdef _WIN32
/* Reserve all memory space except the "huge" `global_size_b`. This is
* required for Windows but we don't do this for Linux since it lets us run
* more processes in parallel without running out of memory immediately
* (though we do risk it later on) */
memfd_reserve((char*)global_storage, sizeof(global_storage[0]));
memfd_reserve((char*)heap, heap_init - (char*)heap);
#endif
}