static void define_globals()

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
}