완료됨
ptmalloc의 arena에 대한 질문

안녕하세요. ptmalloc을 배우던 중 arena에 대한 궁금증이 생겨서 질문을 남기게 되었습니다.

" 멀티 쓰레드 환경에서 ptmalloc은 레이스 컨디션 을 막기 위해 arena에 접근할 때 arena에 락 을 적용합니다. 그런데 이 방식을 사용하면 레이스 컨디션은 막을 수 있지만, 반대로 병목 현상을 일으킬 수 있습니다.*

ptmalloc은 이를 최대한 피하기 위해 최대 64개의 arena를 생성할 수 있게 하고 있습니다. arena에 락이 걸려서 대기해야 하는 경우, 새로운 arena를 생성해서 이를 피할 수 있습니다."

강의에 위와 같은 설명이 존재합니다.

그런데 arena가 공유 자원에 대한 레이스 컨디션을 막기 위해 락을 적용하는데, 여기서 병목 현상을 피하기 위해 arena를 새로 생성한다는 것에서 의문점이 있습니다.

arena가 새로 생성되더라도 결국 공유 자원에 대한 레이스 컨디션을 막으려면 새로 생성된 arena도 이미 한 쓰레드가 다른 arena를 통해 bin에 접근하고 있다면, 새로 생성된 arena에서도 접근할 수 없게 막아야 하는 것 아닌가요 ?

새로 생성된 arena가 어떻게 레이스 컨디션을 피하면서 병목 현상을 줄일 수 있는지 궁금합니다.

읽어주셔서 감사드립니다.

#시스템해킹 #배경지식 #ptmalloc2
작성자 정보
더 깊이 있는 답변이 필요할 때
드림핵 팀과 멘토에게 직접 문의해 보세요!
답변 1
qwerty_io
대표 업적 없음
qwerty_io
대표 업적 없음

arena는 다음과 같은 구조를 가지고 있습니다.

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];

  /* 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];

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

  /* 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;
};

위의 내용을 보면, arena는 고유의 bins을 가집니다. 따라서 한 스레드가 한 arena만 사용한다면 각 스레드는 다른 스레드의 할당자와 완전히 분리되어 있으므로 병목현상을 피할 수 있습니다.

만약 다른 스레드가 free()등의 이유로 다른 스레드가 접근하고 있는 arena를 사용해야 하는 경우 병목이 발생할 수 있지만, 이 경우는 일반적으로 많이 발생하지 않으므로 하나의 arena를 사용하는 것보다 여러 개의 arena를 사용하는 것이 병목현상을 크게 줄일 수 있습니다.

2024.08.28. 17:53