Prérequis

Hello ! o/

Aaaah.. les arenas :) Les arenas dans ptmalloc2 sont simplement les structures de données qui permette de gérer la heap correctement dans sa mémoire. Pour introduire les arenas dans le game de ptmalloc2, voici la structure de données (directement tirée de malloc.c évidemment):

struct malloc_state
{
  /* Serialize access.  */
  __libc_lock_define (, mutex);

  /* Flags (formerly in max_fast).  */
  int flags;

  /* Set if the fastbin chunks contain recently inserted free blocks.  */
  /* Note this is a bool but not all targets support atomics on booleans.  */
  int have_fastchunks;

  /* Fastbins */
  mfastbinptr fastbinsY[NFASTBINS]; // NFASTBINS = 10

  /* Base of the topmost chunk -- not otherwise kept in a bin */
  mchunkptr top;

  /* The remainder from the most recent split of a small request */
  mchunkptr last_remainder;

  /* Normal bins packed as described above */
  mchunkptr bins[NBINS * 2 - 2]; // NBINS = 128

  /* Bitmap of bins */
  unsigned int binmap[BINMAPSIZE]; // BINMAPSIZE = 4

  /* Linked list */
  struct malloc_state *next;

  /* Linked list for free arenas.  Access to this field is serialized
     by free_list_lock in arena.c.  */
  struct malloc_state *next_free;

  /* Number of threads attached to this arena.  0 if the arena is on
     the free list.  Access to this field is serialized by
     free_list_lock in arena.c.  */
  INTERNAL_SIZE_T attached_threads;

  /* Memory allocated from the system in this arena.  */
  INTERNAL_SIZE_T system_mem;
  INTERNAL_SIZE_T max_system_mem;
};

Ce qu’il faut retenir de cette structure de données c’est que les arenas ont:

Dans un programme single-threadé, absolument tous les chunks sont gérés par main_arena

static struct malloc_state main_arena =
{
  .mutex = _LIBC_LOCK_INITIALIZER,
  .next = &main_arena,
  .attached_threads = 1
};

Evidemment main_arena fait référence au bit NON_MAIN_ARENA des chunks, qui, je le rappelle, est 0 si le chunk appartient à main_arena.

Multi-threaded heap

Dans un cas où vous avez une implémentation multi-threadée, glibc a tout prévu pour vous ! Dans un programme multi-threadé vous aurez.. plusieurs heaps et donc plusieurs arenas qui sont toutes reliées les unes aux autres sous la forme d’une jolie liste chaînée :)

typedef struct _heap_info
{
  mstate ar_ptr; /* Arena for this heap. */
  struct _heap_info *prev; /* Previous heap. */
  size_t size;   /* Current size in bytes. */
  size_t mprotect_size; /* Size in bytes that has been mprotected
                           PROT_READ|PROT_WRITE.  */
  /* Make sure the following data is properly aligned, particularly
     that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
     MALLOC_ALIGNMENT. */
  char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK];
} heap_info;

Ces heaps ne seront pas générées avec brk/sbrk, mais avec mmap, et la main_arena sera une simple thread_arena. On pourra donc avoir ce gros schéma pour illustrer nos propos

Pour conclure, notez aussi qu’une arena peut gérer plusieurs heaps !

La seule chose qui peut paraître sombre est que le top de la heap aux adresses basses est free, et qu’il pointe vers celle aux adresses plus hautes.

La suite ici !