[libc-commits] [libc] [libc] add snmalloc as an alternative allocator to libc (PR #122284)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Wed Mar 26 12:42:39 PDT 2025


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/122284

>From bd44929868ec78f19408a26d86f133b6b402ce88 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 9 Jan 2025 22:57:57 +0800
Subject: [PATCH 01/14] POC: add snmalloc as an alternative allocator to libc

---
 libc/src/stdlib/CMakeLists.txt             | 41 +++++++++++-
 libc/src/stdlib/snmalloc/CMakeLists.txt    | 75 ++++++++++++++++++++++
 libc/src/stdlib/snmalloc/aligned_alloc.cpp |  0
 libc/src/stdlib/snmalloc/calloc.cpp        |  0
 libc/src/stdlib/snmalloc/free.cpp          |  0
 libc/src/stdlib/snmalloc/malloc.cpp        |  9 +++
 libc/src/stdlib/snmalloc/mallopt.cpp       |  0
 libc/src/stdlib/snmalloc/realloc.cpp       |  0
 libc/src/stdlib/snmalloc/support.h         | 14 ++++
 9 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/stdlib/snmalloc/CMakeLists.txt
 create mode 100644 libc/src/stdlib/snmalloc/aligned_alloc.cpp
 create mode 100644 libc/src/stdlib/snmalloc/calloc.cpp
 create mode 100644 libc/src/stdlib/snmalloc/free.cpp
 create mode 100644 libc/src/stdlib/snmalloc/malloc.cpp
 create mode 100644 libc/src/stdlib/snmalloc/mallopt.cpp
 create mode 100644 libc/src/stdlib/snmalloc/realloc.cpp
 create mode 100644 libc/src/stdlib/snmalloc/support.h

diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 63eb358717656..d9b28cd79b240 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -346,7 +346,46 @@ add_entrypoint_object(
 )
 
 if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
-  if(LLVM_LIBC_INCLUDE_SCUDO)
+  if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+    message(STATUS "Including snmalloc as the allocator, source directory: ${LLVM_LIBC_INCLUDE_SNMALLOC}")
+    add_subdirectory(snmalloc)
+    add_entrypoint_object(
+      malloc
+      ALIAS
+      DEPENDS
+        .snmalloc.malloc
+    )
+    add_entrypoint_object(
+      calloc
+      ALIAS
+      DEPENDS
+        .snmalloc.calloc
+    )
+    add_entrypoint_object(
+      realloc
+      ALIAS
+      DEPENDS
+        .snmalloc.realloc
+    )
+    add_entrypoint_object(
+      aligned_alloc
+      ALIAS
+      DEPENDS
+        .snmalloc.aligned_alloc
+    )
+    add_entrypoint_object(
+      free
+      ALIAS
+      DEPENDS
+        .snmalloc.free
+    )
+    add_entrypoint_object(
+      mallopt
+      ALIAS
+      DEPENDS
+        .snmalloc.mallopt
+    )
+  elseif(LLVM_LIBC_INCLUDE_SCUDO)
     set(SCUDO_DEPS "")
 
     include(${LIBC_SOURCE_DIR}/../compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake)
diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
new file mode 100644
index 0000000000000..3971ea42db174
--- /dev/null
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -0,0 +1,75 @@
+set(SNMALLOC_USE_SELF_VENDORED_STL ON CACHE BOOL "use freestanding snmalloc setup" FORCE)
+set(SNMALLOC_BUILD_TESTING OFF CACHE BOOL "disable snmalloc tests" FORCE)
+set(SNMALLOC_HEADER_ONLY_LIBRARY ON CACHE BOOL "use snmalloc as header only library" FORCE)
+
+# Disable installation
+macro (install)
+endmacro ()
+
+add_subdirectory(${LLVM_LIBC_INCLUDE_SNMALLOC} ${CMAKE_CURRENT_BINARY_DIR}/snmalloc EXCLUDE_FROM_ALL)
+
+target_compile_options(
+  snmalloc 
+  INTERFACE 
+    -ffreestanding
+    -nostdinc 
+    -Wno-newline-eof 
+    -Wno-extra-semi
+    -Wno-unused-command-line-argument
+    -Wno-ctad-maybe-unsupported
+    # TODO: define this
+    -DSTDERR_FILENO=2
+    -include ${CMAKE_CURRENT_SOURCE_DIR}/support.h
+    # include_directories does not propagate, use options instead
+    -isystem ${COMPILER_RESOURCE_DIR}/include
+    -isystem ${LIBC_INCLUDE_DIR}
+)
+add_dependencies(snmalloc libc-headers)
+
+add_entrypoint_object(
+  malloc
+  SRCS
+    malloc.cpp
+  DEPENDS
+    snmalloc
+)
+
+add_entrypoint_object(
+  calloc
+  SRCS
+    calloc.cpp
+  DEPENDS
+    snmalloc
+)
+
+add_entrypoint_object(
+  realloc
+  SRCS
+    realloc.cpp
+  DEPENDS
+    snmalloc
+)
+
+add_entrypoint_object(
+  aligned_alloc
+  SRCS
+    aligned_alloc.cpp
+  DEPENDS
+    snmalloc
+)
+
+add_entrypoint_object(
+  free
+  SRCS
+    free.cpp
+  DEPENDS
+    snmalloc
+)
+
+add_entrypoint_object(
+  mallopt
+  SRCS
+    mallopt.cpp
+  DEPENDS
+    snmalloc
+)
diff --git a/libc/src/stdlib/snmalloc/aligned_alloc.cpp b/libc/src/stdlib/snmalloc/aligned_alloc.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdlib/snmalloc/calloc.cpp b/libc/src/stdlib/snmalloc/calloc.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdlib/snmalloc/free.cpp b/libc/src/stdlib/snmalloc/free.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdlib/snmalloc/malloc.cpp b/libc/src/stdlib/snmalloc/malloc.cpp
new file mode 100644
index 0000000000000..644f2eef0ed2b
--- /dev/null
+++ b/libc/src/stdlib/snmalloc/malloc.cpp
@@ -0,0 +1,9 @@
+#include "src/stdlib/malloc.h"
+#include "snmalloc/snmalloc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) {
+  return snmalloc::libc::malloc(size);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/mallopt.cpp b/libc/src/stdlib/snmalloc/mallopt.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdlib/snmalloc/realloc.cpp b/libc/src/stdlib/snmalloc/realloc.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdlib/snmalloc/support.h b/libc/src/stdlib/snmalloc/support.h
new file mode 100644
index 0000000000000..4909667c1a50d
--- /dev/null
+++ b/libc/src/stdlib/snmalloc/support.h
@@ -0,0 +1,14 @@
+#include "src/sys/random/getrandom.h"
+
+// TODO: define this
+inline int getentropy(void *buf, size_t size) {
+  while (size > 0) {
+    ssize_t ret = LIBC_NAMESPACE::getrandom(buf, size, 0);
+    if (ret < 0) {
+      return -1;
+    }
+    buf = (char *)buf + ret;
+    size -= ret;
+  }
+  return 0;
+}

>From 56198923b9f784f054d525b62448ce7f5ffbbc12 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 16 Jan 2025 04:08:22 +0000
Subject: [PATCH 02/14] adjust build

---
 libc/src/stdlib/snmalloc/CMakeLists.txt |  2 +-
 libc/src/stdlib/snmalloc/free.cpp       | 17 +++++++++++++++++
 libc/src/stdlib/snmalloc/malloc.cpp     |  8 ++++++++
 libc/src/stdlib/snmalloc/support.h      | 14 --------------
 4 files changed, 26 insertions(+), 15 deletions(-)
 delete mode 100644 libc/src/stdlib/snmalloc/support.h

diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index 3971ea42db174..516505c09a13d 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -19,7 +19,7 @@ target_compile_options(
     -Wno-ctad-maybe-unsupported
     # TODO: define this
     -DSTDERR_FILENO=2
-    -include ${CMAKE_CURRENT_SOURCE_DIR}/support.h
+    -DSNMALLOC_USE_PTHREAD_DESTRUCTORS
     # include_directories does not propagate, use options instead
     -isystem ${COMPILER_RESOURCE_DIR}/include
     -isystem ${LIBC_INCLUDE_DIR}
diff --git a/libc/src/stdlib/snmalloc/free.cpp b/libc/src/stdlib/snmalloc/free.cpp
index e69de29bb2d1d..a3160c15d0df3 100644
--- a/libc/src/stdlib/snmalloc/free.cpp
+++ b/libc/src/stdlib/snmalloc/free.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of free --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/free.h"
+#include "snmalloc/snmalloc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(void, free, (void * ptr)) {
+  return snmalloc::libc::free(ptr);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/malloc.cpp b/libc/src/stdlib/snmalloc/malloc.cpp
index 644f2eef0ed2b..ab58e63743016 100644
--- a/libc/src/stdlib/snmalloc/malloc.cpp
+++ b/libc/src/stdlib/snmalloc/malloc.cpp
@@ -1,3 +1,11 @@
+//===-- Implementation of malloc ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
 #include "src/stdlib/malloc.h"
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
diff --git a/libc/src/stdlib/snmalloc/support.h b/libc/src/stdlib/snmalloc/support.h
deleted file mode 100644
index 4909667c1a50d..0000000000000
--- a/libc/src/stdlib/snmalloc/support.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "src/sys/random/getrandom.h"
-
-// TODO: define this
-inline int getentropy(void *buf, size_t size) {
-  while (size > 0) {
-    ssize_t ret = LIBC_NAMESPACE::getrandom(buf, size, 0);
-    if (ret < 0) {
-      return -1;
-    }
-    buf = (char *)buf + ret;
-    size -= ret;
-  }
-  return 0;
-}

>From bebcfc9dd0ab747659e05d147ad4e0a372c48a8c Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 16 Jan 2025 04:26:12 +0000
Subject: [PATCH 03/14] implement all symbols

---
 libc/src/stdlib/snmalloc/aligned_alloc.cpp | 17 +++++++++++++++++
 libc/src/stdlib/snmalloc/calloc.cpp        | 17 +++++++++++++++++
 libc/src/stdlib/snmalloc/free.cpp          |  2 +-
 libc/src/stdlib/snmalloc/mallopt.cpp       | 13 +++++++++++++
 libc/src/stdlib/snmalloc/realloc.cpp       | 17 +++++++++++++++++
 5 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/libc/src/stdlib/snmalloc/aligned_alloc.cpp b/libc/src/stdlib/snmalloc/aligned_alloc.cpp
index e69de29bb2d1d..ee1d74ca9c778 100644
--- a/libc/src/stdlib/snmalloc/aligned_alloc.cpp
+++ b/libc/src/stdlib/snmalloc/aligned_alloc.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of aligned_alloc -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/aligned_alloc.h"
+#include "snmalloc/snmalloc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(void *, aligned_alloc, (size_t alignment, size_t size)) {
+  return snmalloc::libc::aligned_alloc(alignment, size);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/calloc.cpp b/libc/src/stdlib/snmalloc/calloc.cpp
index e69de29bb2d1d..39af67607bf70 100644
--- a/libc/src/stdlib/snmalloc/calloc.cpp
+++ b/libc/src/stdlib/snmalloc/calloc.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of calloc ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/calloc.h"
+#include "snmalloc/snmalloc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(void *, calloc, (size_t num, size_t size)) {
+  return snmalloc::libc::calloc(num, size);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/free.cpp b/libc/src/stdlib/snmalloc/free.cpp
index a3160c15d0df3..eb403710fffad 100644
--- a/libc/src/stdlib/snmalloc/free.cpp
+++ b/libc/src/stdlib/snmalloc/free.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(void, free, (void * ptr)) {
+LLVM_LIBC_FUNCTION(void, free, (void *ptr)) {
   return snmalloc::libc::free(ptr);
 }
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/mallopt.cpp b/libc/src/stdlib/snmalloc/mallopt.cpp
index e69de29bb2d1d..c52d68e3d5223 100644
--- a/libc/src/stdlib/snmalloc/mallopt.cpp
+++ b/libc/src/stdlib/snmalloc/mallopt.cpp
@@ -0,0 +1,13 @@
+//===-- Implementation of mallopt stub ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(int, mallopt, (int, int)) { return 0; }
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/snmalloc/realloc.cpp b/libc/src/stdlib/snmalloc/realloc.cpp
index e69de29bb2d1d..36972e0a2232e 100644
--- a/libc/src/stdlib/snmalloc/realloc.cpp
+++ b/libc/src/stdlib/snmalloc/realloc.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of realloc -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/realloc.h"
+#include "snmalloc/snmalloc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(void *, realloc, (void *ptr, size_t size)) {
+  return snmalloc::libc::realloc(ptr, size);
+}
+} // namespace LIBC_NAMESPACE_DECL

>From 9633f4d62e21c436af7465cdd469e8fb0d7b7099 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 16 Jan 2025 05:09:37 +0000
Subject: [PATCH 04/14] setup dependencies

---
 libc/src/stdlib/snmalloc/CMakeLists.txt | 43 +++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index 516505c09a13d..cc7172c947c4c 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -24,8 +24,46 @@ target_compile_options(
     -isystem ${COMPILER_RESOURCE_DIR}/include
     -isystem ${LIBC_INCLUDE_DIR}
 )
+
 add_dependencies(snmalloc libc-headers)
 
+set(SNMALLOC_DEPS
+  # includes
+  libc.include.errno
+  libc.include.fcntl
+  libc.include.limits
+  libc.include.pthread
+  libc.include.stdio
+  libc.include.stdint
+  libc.include.stdlib
+  libc.include.string
+  libc.include.strings
+  libc.include.sys_mman
+  libc.include.sys_prctl
+  libc.include.sys_random
+  libc.include.sys_syscall
+  libc.include.sys_uio
+  libc.include.unistd
+  # symbols
+  libc.src.errno.errno
+  libc.src.fcntl.open
+  libc.src.pthread.pthread_key_create
+  libc.src.pthread.pthread_setspecific
+  libc.src.stdlib.abort
+  libc.src.stdlib.atexit
+  libc.src.string.memset
+  libc.src.string.strlen
+  libc.src.sys.mman.madvise
+  libc.src.sys.mman.mmap
+  libc.src.sys.uio.writev
+  libc.src.time.clock_gettime
+  libc.src.unistd.__llvm_libc_syscall
+  libc.src.unistd.close
+  libc.src.unistd.fsync
+  libc.src.unistd.getentropy
+  libc.src.unistd.read
+)
+
 add_entrypoint_object(
   malloc
   SRCS
@@ -40,6 +78,7 @@ add_entrypoint_object(
     calloc.cpp
   DEPENDS
     snmalloc
+    ${SNMALLOC_DEPS}
 )
 
 add_entrypoint_object(
@@ -48,6 +87,7 @@ add_entrypoint_object(
     realloc.cpp
   DEPENDS
     snmalloc
+    ${SNMALLOC_DEPS}
 )
 
 add_entrypoint_object(
@@ -56,6 +96,7 @@ add_entrypoint_object(
     aligned_alloc.cpp
   DEPENDS
     snmalloc
+    ${SNMALLOC_DEPS}
 )
 
 add_entrypoint_object(
@@ -64,6 +105,7 @@ add_entrypoint_object(
     free.cpp
   DEPENDS
     snmalloc
+    ${SNMALLOC_DEPS}
 )
 
 add_entrypoint_object(
@@ -72,4 +114,5 @@ add_entrypoint_object(
     mallopt.cpp
   DEPENDS
     snmalloc
+    ${SNMALLOC_DEPS}
 )

>From 5621efec2e4b46c381c13da701358c54d6d72b9f Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 16 Jan 2025 06:12:42 +0000
Subject: [PATCH 05/14] make hermetic build pass with snmalloc

---
 libc/src/stdlib/snmalloc/CMakeLists.txt |  1 +
 libc/src/stdlib/snmalloc/override.h     | 32 +++++++++++++++++++++++++
 libc/test/src/stdlib/CMakeLists.txt     |  8 ++++---
 3 files changed, 38 insertions(+), 3 deletions(-)
 create mode 100644 libc/src/stdlib/snmalloc/override.h

diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index cc7172c947c4c..e360b36f5fb3a 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -21,6 +21,7 @@ target_compile_options(
     -DSTDERR_FILENO=2
     -DSNMALLOC_USE_PTHREAD_DESTRUCTORS
     # include_directories does not propagate, use options instead
+    -include ${CMAKE_CURRENT_SOURCE_DIR}/override.h
     -isystem ${COMPILER_RESOURCE_DIR}/include
     -isystem ${LIBC_INCLUDE_DIR}
 )
diff --git a/libc/src/stdlib/snmalloc/override.h b/libc/src/stdlib/snmalloc/override.h
new file mode 100644
index 0000000000000..a36a6316790fb
--- /dev/null
+++ b/libc/src/stdlib/snmalloc/override.h
@@ -0,0 +1,32 @@
+//===-- Macro Override for SnMalloc ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// skip special headers
+#define LLVM_LIBC_COMMON_H
+#define LLVM_LIBC_ERRNO_H
+
+// define common macros
+#define __BEGIN_C_DECLS namespace LIBC_NAMESPACE {
+#define __END_C_DECLS                                                          \
+  }                                                                            \
+  using namespace LIBC_NAMESPACE;
+
+#define _Noreturn [[noreturn]]
+#define _Alignas alignas
+#define _Static_assert static_assert
+#define _Alignof alignof
+#define _Thread_local thread_local
+
+// Use empty definition to avoid spec mismatching
+// We are building internally anyway, hence noexcept does not matter here
+#define __NOEXCEPT
+
+// Enforce internal errno implementation
+#include "hdr/errno_macros.h"
+#include "src/errno/libc_errno.h"
+#define errno libc_errno
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 90d7b7a55dbe6..6ddade17e1e74 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -441,9 +441,11 @@ if(LLVM_LIBC_FULL_BUILD)
       libc.src.stdlib.quick_exit
   )
 
-  # Only baremetal and GPU has an in-tree 'malloc' implementation.
-  if((LIBC_TARGET_OS_IS_BAREMETAL OR LIBC_TARGET_OS_IS_GPU) AND
-      NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
+  # Only baremetal, snmalloc and GPU has an in-tree 'malloc'
+  # implementation.
+  if(LIBC_TARGET_OS_IS_BAREMETAL
+      OR (LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
+      OR NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}")
     add_libc_test(
       malloc_test
       HERMETIC_TEST_ONLY

>From 1dc839b65dc9865ba853098e751b203fff484266 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 19 Jan 2025 09:04:54 +0000
Subject: [PATCH 06/14] use _malloc_thread_cleanup hook in fullbuild mode

---
 libc/src/__support/threads/linux/CMakeLists.txt |  5 +++++
 libc/src/__support/threads/linux/thread.cpp     | 10 ++++++++++
 libc/src/stdlib/CMakeLists.txt                  |  9 +++++++++
 libc/src/stdlib/atexit.cpp                      |  9 +++++++++
 libc/src/stdlib/snmalloc/CMakeLists.txt         |  5 -----
 libc/src/stdlib/snmalloc/aligned_alloc.cpp      |  4 +++-
 libc/src/stdlib/snmalloc/calloc.cpp             |  4 +++-
 libc/src/stdlib/snmalloc/free.cpp               |  4 +++-
 libc/src/stdlib/snmalloc/malloc.cpp             |  4 +++-
 libc/src/stdlib/snmalloc/override.h             |  4 ++++
 libc/src/stdlib/snmalloc/realloc.cpp            |  4 +++-
 11 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt
index 364e7e2b90585..74dfef3d15073 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -71,6 +71,10 @@ add_header_library(
     libc.src.__support.threads.mutex_common
 )
 
+if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+  set (libc_malloc_thread_cleanup_flag "-DLIBC_USE_MALLOC_THREAD_CLEANUP")
+endif()
+
 add_object_library(
   thread
   SRCS
@@ -89,6 +93,7 @@ add_object_library(
     libc.src.__support.threads.thread_common
   COMPILE_OPTIONS
     ${libc_opt_high_flag}
+    ${libc_malloc_thread_cleanup_flag}
     -fno-omit-frame-pointer # This allows us to sniff out the thread args from
                             # the new thread's stack reliably.
     -Wno-frame-address      # Yes, calling __builtin_return_address with a
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index c531d74c53355..a80c04a24fdba 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -482,6 +482,11 @@ int Thread::get_name(cpp::StringStream &name) const {
   return 0;
 }
 
+#ifdef LIBC_USE_MALLOC_THREAD_CLEANUP
+// This symbol may not be defined if libc is not built with allocator
+extern "C" [[gnu::weak]] void _malloc_thread_cleanup();
+#endif
+
 void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
   auto attrib = self.attrib;
 
@@ -494,6 +499,11 @@ void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
   // different thread. The destructors of thread local and TSS objects should
   // be called by the thread which owns them.
   internal::call_atexit_callbacks(attrib);
+#ifdef LIBC_USE_MALLOC_THREAD_CLEANUP
+  // teardown TLS heap
+  if (_malloc_thread_cleanup)
+    _malloc_thread_cleanup();
+#endif
 
   uint32_t joinable_state = uint32_t(DetachState::JOINABLE);
   if (!attrib->detach_state.compare_exchange_strong(
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index d9b28cd79b240..7671ed9604937 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -348,6 +348,9 @@ add_entrypoint_object(
 if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
   if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
     message(STATUS "Including snmalloc as the allocator, source directory: ${LLVM_LIBC_INCLUDE_SNMALLOC}")
+    if (NOT LLVM_LIBC_FULL_BUILD)
+      message(FATAL_ERROR "Snmalloc can only be included when fullbuild mode is enabled")
+    endif()
     add_subdirectory(snmalloc)
     add_entrypoint_object(
       malloc
@@ -617,6 +620,10 @@ add_header_library(
 )
 endif()
 
+if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+  set (libc_malloc_thread_cleanup_flag "-DLIBC_USE_MALLOC_THREAD_CLEANUP")
+endif()
+
 add_entrypoint_object(
   atexit
   SRCS
@@ -627,6 +634,8 @@ add_entrypoint_object(
     20 # For constinit
   DEPENDS
     .exit_handler
+  COMPILE_OPTIONS
+    ${libc_malloc_thread_cleanup_flag}
 )
 
 add_entrypoint_object(
diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 799aad136bda5..e5baca946c85b 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -18,6 +18,11 @@ constinit ExitCallbackList atexit_callbacks;
 Mutex handler_list_mtx(false, false, false, false);
 [[gnu::weak]] extern void teardown_main_tls();
 
+#ifdef LIBC_USE_MALLOC_THREAD_CLEANUP
+// This symbol may not be defined if libc is not built with allocator
+extern "C" [[gnu::weak]] void _malloc_thread_cleanup();
+#endif
+
 extern "C" {
 
 int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
@@ -27,6 +32,10 @@ int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
 void __cxa_finalize(void *dso) {
   if (!dso) {
     call_exit_callbacks(atexit_callbacks);
+#ifdef LIBC_USE_MALLOC_THREAD_CLEANUP
+    if (_malloc_thread_cleanup)
+      _malloc_thread_cleanup();
+#endif
     if (teardown_main_tls)
       teardown_main_tls();
   }
diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index e360b36f5fb3a..b980738abb750 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -17,11 +17,6 @@ target_compile_options(
     -Wno-extra-semi
     -Wno-unused-command-line-argument
     -Wno-ctad-maybe-unsupported
-    # TODO: define this
-    -DSTDERR_FILENO=2
-    -DSNMALLOC_USE_PTHREAD_DESTRUCTORS
-    # include_directories does not propagate, use options instead
-    -include ${CMAKE_CURRENT_SOURCE_DIR}/override.h
     -isystem ${COMPILER_RESOURCE_DIR}/include
     -isystem ${LIBC_INCLUDE_DIR}
 )
diff --git a/libc/src/stdlib/snmalloc/aligned_alloc.cpp b/libc/src/stdlib/snmalloc/aligned_alloc.cpp
index ee1d74ca9c778..7e209c170d613 100644
--- a/libc/src/stdlib/snmalloc/aligned_alloc.cpp
+++ b/libc/src/stdlib/snmalloc/aligned_alloc.cpp
@@ -6,9 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/aligned_alloc.h"
+#include "src/stdlib/snmalloc/override.h"
+
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
+#include "src/stdlib/aligned_alloc.h"
 
 namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(void *, aligned_alloc, (size_t alignment, size_t size)) {
diff --git a/libc/src/stdlib/snmalloc/calloc.cpp b/libc/src/stdlib/snmalloc/calloc.cpp
index 39af67607bf70..7bac3f6b1b0e6 100644
--- a/libc/src/stdlib/snmalloc/calloc.cpp
+++ b/libc/src/stdlib/snmalloc/calloc.cpp
@@ -6,9 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/calloc.h"
+#include "src/stdlib/snmalloc/override.h"
+
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
+#include "src/stdlib/calloc.h"
 
 namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(void *, calloc, (size_t num, size_t size)) {
diff --git a/libc/src/stdlib/snmalloc/free.cpp b/libc/src/stdlib/snmalloc/free.cpp
index eb403710fffad..fa8f94f73a563 100644
--- a/libc/src/stdlib/snmalloc/free.cpp
+++ b/libc/src/stdlib/snmalloc/free.cpp
@@ -6,9 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/free.h"
+#include "src/stdlib/snmalloc/override.h"
+
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
+#include "src/stdlib/free.h"
 
 namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(void, free, (void *ptr)) {
diff --git a/libc/src/stdlib/snmalloc/malloc.cpp b/libc/src/stdlib/snmalloc/malloc.cpp
index ab58e63743016..ff4352687ed0d 100644
--- a/libc/src/stdlib/snmalloc/malloc.cpp
+++ b/libc/src/stdlib/snmalloc/malloc.cpp
@@ -6,9 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/malloc.h"
+#include "src/stdlib/snmalloc/override.h"
+
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
+#include "src/stdlib/malloc.h"
 
 namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) {
diff --git a/libc/src/stdlib/snmalloc/override.h b/libc/src/stdlib/snmalloc/override.h
index a36a6316790fb..50f26f8b20386 100644
--- a/libc/src/stdlib/snmalloc/override.h
+++ b/libc/src/stdlib/snmalloc/override.h
@@ -26,6 +26,10 @@
 // We are building internally anyway, hence noexcept does not matter here
 #define __NOEXCEPT
 
+// TODO: define this in stdio.h
+#define STDERR_FILENO 2
+#define SNMALLOC_USE_THREAD_CLEANUP
+
 // Enforce internal errno implementation
 #include "hdr/errno_macros.h"
 #include "src/errno/libc_errno.h"
diff --git a/libc/src/stdlib/snmalloc/realloc.cpp b/libc/src/stdlib/snmalloc/realloc.cpp
index 36972e0a2232e..bdafc2d0cc759 100644
--- a/libc/src/stdlib/snmalloc/realloc.cpp
+++ b/libc/src/stdlib/snmalloc/realloc.cpp
@@ -6,9 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/realloc.h"
+#include "src/stdlib/snmalloc/override.h"
+
 #include "snmalloc/snmalloc.h"
 #include "src/__support/common.h"
+#include "src/stdlib/realloc.h"
 
 namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(void *, realloc, (void *ptr, size_t size)) {

>From 7c214fe2844224d3dad3715ff1b3512c70fdc983 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 19 Jan 2025 10:00:12 +0000
Subject: [PATCH 07/14] minor cleanup

---
 libc/src/stdlib/snmalloc/CMakeLists.txt | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index b980738abb750..08616267bb2b9 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -28,7 +28,6 @@ set(SNMALLOC_DEPS
   libc.include.errno
   libc.include.fcntl
   libc.include.limits
-  libc.include.pthread
   libc.include.stdio
   libc.include.stdint
   libc.include.stdlib
@@ -43,10 +42,7 @@ set(SNMALLOC_DEPS
   # symbols
   libc.src.errno.errno
   libc.src.fcntl.open
-  libc.src.pthread.pthread_key_create
-  libc.src.pthread.pthread_setspecific
   libc.src.stdlib.abort
-  libc.src.stdlib.atexit
   libc.src.string.memset
   libc.src.string.strlen
   libc.src.sys.mman.madvise

>From bde5f6e3984948881e33188219a415b7e573e2bc Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 26 Jan 2025 12:40:08 +0000
Subject: [PATCH 08/14] address code related reviews

---
 libc/src/__support/threads/linux/CMakeLists.txt | 2 +-
 libc/src/stdlib/CMakeLists.txt                  | 6 +++---
 libc/src/stdlib/snmalloc/CMakeLists.txt         | 2 +-
 libc/test/src/stdlib/CMakeLists.txt             | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt
index 74dfef3d15073..80a060428d86b 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -71,7 +71,7 @@ add_header_library(
     libc.src.__support.threads.mutex_common
 )
 
-if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+if (NOT "${LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
   set (libc_malloc_thread_cleanup_flag "-DLIBC_USE_MALLOC_THREAD_CLEANUP")
 endif()
 
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 7671ed9604937..dfd2b19506c91 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -346,8 +346,8 @@ add_entrypoint_object(
 )
 
 if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
-  if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
-    message(STATUS "Including snmalloc as the allocator, source directory: ${LLVM_LIBC_INCLUDE_SNMALLOC}")
+  if (NOT "${LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+    message(STATUS "Including snmalloc as the allocator, source directory: ${LIBC_INCLUDE_SNMALLOC}")
     if (NOT LLVM_LIBC_FULL_BUILD)
       message(FATAL_ERROR "Snmalloc can only be included when fullbuild mode is enabled")
     endif()
@@ -620,7 +620,7 @@ add_header_library(
 )
 endif()
 
-if (NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
+if (NOT "${LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
   set (libc_malloc_thread_cleanup_flag "-DLIBC_USE_MALLOC_THREAD_CLEANUP")
 endif()
 
diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index 08616267bb2b9..7632ffa17036d 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -6,7 +6,7 @@ set(SNMALLOC_HEADER_ONLY_LIBRARY ON CACHE BOOL "use snmalloc as header only libr
 macro (install)
 endmacro ()
 
-add_subdirectory(${LLVM_LIBC_INCLUDE_SNMALLOC} ${CMAKE_CURRENT_BINARY_DIR}/snmalloc EXCLUDE_FROM_ALL)
+add_subdirectory(${LIBC_INCLUDE_SNMALLOC} ${CMAKE_CURRENT_BINARY_DIR}/snmalloc EXCLUDE_FROM_ALL)
 
 target_compile_options(
   snmalloc 
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 6ddade17e1e74..82f4f1e9d2d55 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -445,7 +445,7 @@ if(LLVM_LIBC_FULL_BUILD)
   # implementation.
   if(LIBC_TARGET_OS_IS_BAREMETAL
       OR (LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
-      OR NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}")
+      OR NOT "${LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
     add_libc_test(
       malloc_test
       HERMETIC_TEST_ONLY

>From d2b71d184789f5d6131bdeba7d688f32a551b3a6 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 26 Jan 2025 12:56:05 +0000
Subject: [PATCH 09/14] add doc

---
 libc/docs/full_host_build.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/libc/docs/full_host_build.rst b/libc/docs/full_host_build.rst
index 12aacf181695a..298c520631956 100644
--- a/libc/docs/full_host_build.rst
+++ b/libc/docs/full_host_build.rst
@@ -140,6 +140,30 @@ allocator for LLVM-libc.
       -DCLANG_DEFAULT_RTLIB=compiler-rt \
       -DCMAKE_INSTALL_PREFIX=$SYSROOT
 
+Libc can optionally use `SnMalloc <https://github.com/microsoft/snmalloc>`_ as its
+allocator implementation. ``SnMalloc`` is a modern allocator implementation with excellent
+multicore performance. Please refer to ``SnMalloc``'s repositories for more information.
+
+To setup ``SnMalloc``, use the following ``cmake`` configuration instead:
+
+.. code-block:: sh
+   $> git clone https://github.com/microsoft/snmalloc
+   $> export SNMALLOC_DIR=$(realpath snmalloc)
+   $> cd /path/to/llvm-project
+   $> cmake -S runtimes \
+      -B build \
+      -G Ninja \
+      -DCMAKE_C_COMPILER=clang \
+      -DCMAKE_CXX_COMPILER=clang++ \
+      -DLLVM_ENABLE_RUNTIMES="libc" \
+      -DLLVM_LIBC_FULL_BUILD=ON \
+      -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+      -DLLVM_LIBC_INCLUDE_SNMALLOC="$SNMALLOC_DIR"
+
+.. note::
+   LLVM's libc does not vendor ``SnMalloc``. The commit known to work is
+   ``e3e558472de805b2408e2ee24a055ef0b7c38423``.
+
 Build and install
 =================
 

>From 78e41bcbeee8e42f7917b894365b59e185fca7d9 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Mon, 27 Jan 2025 01:19:22 +0000
Subject: [PATCH 10/14] fix doc build

---
 libc/docs/full_host_build.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libc/docs/full_host_build.rst b/libc/docs/full_host_build.rst
index 298c520631956..923f5fbae3188 100644
--- a/libc/docs/full_host_build.rst
+++ b/libc/docs/full_host_build.rst
@@ -147,6 +147,7 @@ multicore performance. Please refer to ``SnMalloc``'s repositories for more info
 To setup ``SnMalloc``, use the following ``cmake`` configuration instead:
 
 .. code-block:: sh
+
    $> git clone https://github.com/microsoft/snmalloc
    $> export SNMALLOC_DIR=$(realpath snmalloc)
    $> cd /path/to/llvm-project

>From dccba980d5263c0080b5b7554307d50d43f454f2 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Tue, 28 Jan 2025 23:46:17 +0000
Subject: [PATCH 11/14] address code reviews

---
 libc/docs/full_host_build.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/docs/full_host_build.rst b/libc/docs/full_host_build.rst
index 923f5fbae3188..ad12d380f8a1a 100644
--- a/libc/docs/full_host_build.rst
+++ b/libc/docs/full_host_build.rst
@@ -159,7 +159,7 @@ To setup ``SnMalloc``, use the following ``cmake`` configuration instead:
       -DLLVM_ENABLE_RUNTIMES="libc" \
       -DLLVM_LIBC_FULL_BUILD=ON \
       -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-      -DLLVM_LIBC_INCLUDE_SNMALLOC="$SNMALLOC_DIR"
+      -DLIBC_INCLUDE_SNMALLOC="$SNMALLOC_DIR"
 
 .. note::
    LLVM's libc does not vendor ``SnMalloc``. The commit known to work is

>From 2ff652810cf2197266b7e26b763914fdb26af05f Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Fri, 7 Feb 2025 15:26:30 +0000
Subject: [PATCH 12/14] add malloc options

---
 libc/config/config.json | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libc/config/config.json b/libc/config/config.json
index d738aade74427..357746de19b15 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -124,5 +124,11 @@
       "value": true,
       "doc": "Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior."
     }
+  },
+  "stdlib": {
+    "LIBC_MALLOC_IMPLEMENTATION": {
+      "value": "",
+      "doc": "Select the implementation of memory allocator. Leave empty to disable malloc symbols. Possible values are scudo/snmalloc/baremetal"
+    }
   }
 }

>From 95a25bfce6017f20096a37a215131dd62ca4ff7f Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Wed, 26 Mar 2025 15:34:03 -0400
Subject: [PATCH 13/14] update

---
 libc/docs/configure.rst                 |  2 ++
 libc/docs/full_host_build.rst           |  2 +-
 libc/src/stdlib/snmalloc/CMakeLists.txt | 12 ++++++++----
 libc/src/stdlib/snmalloc/override.h     |  4 ++--
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index dee9a63101eb9..71d4c2d146989 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -57,6 +57,8 @@ to learn about the defaults for your platform and target.
     - ``LIBC_CONF_SCANF_DISABLE_INDEX_MODE``: Disable index mode in the scanf format string.
 * **"setjmp" options**
     - ``LIBC_CONF_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER``: Make setjmp save the value of x18, and longjmp restore it. The AArch64 ABI delegates this register to platform ABIs, which can choose whether to make it caller-saved.
+* **"stdlib" options**
+    - ``LIBC_MALLOC_IMPLEMENTATION``: Select the implementation of memory allocator. Leave empty to disable malloc symbols. Possible values are scudo/snmalloc/baremetal
 * **"string" options**
     - ``LIBC_CONF_MEMSET_X86_USE_SOFTWARE_PREFETCHING``: Inserts prefetch for write instructions (PREFETCHW) for memset on x86 to recover performance when hardware prefetcher is disabled.
     - ``LIBC_CONF_STRING_UNSAFE_WIDE_READ``: Read more than a byte at a time to perform byte-string operations like strlen.
diff --git a/libc/docs/full_host_build.rst b/libc/docs/full_host_build.rst
index ad12d380f8a1a..2a876cf817e32 100644
--- a/libc/docs/full_host_build.rst
+++ b/libc/docs/full_host_build.rst
@@ -163,7 +163,7 @@ To setup ``SnMalloc``, use the following ``cmake`` configuration instead:
 
 .. note::
    LLVM's libc does not vendor ``SnMalloc``. The commit known to work is
-   ``e3e558472de805b2408e2ee24a055ef0b7c38423``.
+   ``80bdcd999f1881fd26463a6f5b5aca21600907de``.
 
 Build and install
 =================
diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index 7632ffa17036d..7062fe04b6cd3 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -6,14 +6,16 @@ set(SNMALLOC_HEADER_ONLY_LIBRARY ON CACHE BOOL "use snmalloc as header only libr
 macro (install)
 endmacro ()
 
+set(CMAKE_DISABLE_FIND_PACKAGE_Backtrace ON)
+
 add_subdirectory(${LIBC_INCLUDE_SNMALLOC} ${CMAKE_CURRENT_BINARY_DIR}/snmalloc EXCLUDE_FROM_ALL)
 
 target_compile_options(
-  snmalloc 
-  INTERFACE 
+  snmalloc
+  INTERFACE
     -ffreestanding
-    -nostdinc 
-    -Wno-newline-eof 
+    -nostdinc
+    -Wno-newline-eof
     -Wno-extra-semi
     -Wno-unused-command-line-argument
     -Wno-ctad-maybe-unsupported
@@ -28,6 +30,7 @@ set(SNMALLOC_DEPS
   libc.include.errno
   libc.include.fcntl
   libc.include.limits
+  libc.include.pthread
   libc.include.stdio
   libc.include.stdint
   libc.include.stdlib
@@ -42,6 +45,7 @@ set(SNMALLOC_DEPS
   # symbols
   libc.src.errno.errno
   libc.src.fcntl.open
+  libc.src.pthread.pthread_atfork
   libc.src.stdlib.abort
   libc.src.string.memset
   libc.src.string.strlen
diff --git a/libc/src/stdlib/snmalloc/override.h b/libc/src/stdlib/snmalloc/override.h
index 50f26f8b20386..db08a8d0dc21f 100644
--- a/libc/src/stdlib/snmalloc/override.h
+++ b/libc/src/stdlib/snmalloc/override.h
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // skip special headers
-#define LLVM_LIBC_COMMON_H
+#define _LLVM_LIBC_COMMON_H
 #define LLVM_LIBC_ERRNO_H
 
 // define common macros
@@ -33,4 +33,4 @@
 // Enforce internal errno implementation
 #include "hdr/errno_macros.h"
 #include "src/errno/libc_errno.h"
-#define errno libc_errno
+#define errno ::LIBC_NAMESPACE::libc_errno

>From 4687c273178525417473938f26bacd34971db0fc Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Wed, 26 Mar 2025 15:42:18 -0400
Subject: [PATCH 14/14] remove install masking as it is no longer needed

---
 libc/src/stdlib/snmalloc/CMakeLists.txt | 6 ++----
 libc/src/stdlib/snmalloc/override.h     | 2 +-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/libc/src/stdlib/snmalloc/CMakeLists.txt b/libc/src/stdlib/snmalloc/CMakeLists.txt
index 7062fe04b6cd3..d9ea742e2e792 100644
--- a/libc/src/stdlib/snmalloc/CMakeLists.txt
+++ b/libc/src/stdlib/snmalloc/CMakeLists.txt
@@ -2,10 +2,6 @@ set(SNMALLOC_USE_SELF_VENDORED_STL ON CACHE BOOL "use freestanding snmalloc setu
 set(SNMALLOC_BUILD_TESTING OFF CACHE BOOL "disable snmalloc tests" FORCE)
 set(SNMALLOC_HEADER_ONLY_LIBRARY ON CACHE BOOL "use snmalloc as header only library" FORCE)
 
-# Disable installation
-macro (install)
-endmacro ()
-
 set(CMAKE_DISABLE_FIND_PACKAGE_Backtrace ON)
 
 add_subdirectory(${LIBC_INCLUDE_SNMALLOC} ${CMAKE_CURRENT_BINARY_DIR}/snmalloc EXCLUDE_FROM_ALL)
@@ -58,6 +54,8 @@ set(SNMALLOC_DEPS
   libc.src.unistd.fsync
   libc.src.unistd.getentropy
   libc.src.unistd.read
+  libc.src.pthread.pthread_setspecific
+  libc.src.pthread.pthread_key_create
 )
 
 add_entrypoint_object(
diff --git a/libc/src/stdlib/snmalloc/override.h b/libc/src/stdlib/snmalloc/override.h
index db08a8d0dc21f..d5b9b0b849255 100644
--- a/libc/src/stdlib/snmalloc/override.h
+++ b/libc/src/stdlib/snmalloc/override.h
@@ -28,7 +28,7 @@
 
 // TODO: define this in stdio.h
 #define STDERR_FILENO 2
-#define SNMALLOC_USE_THREAD_CLEANUP
+#define SNMALLOC_USE_PTHREAD_DESTRUCTORS
 
 // Enforce internal errno implementation
 #include "hdr/errno_macros.h"



More information about the libc-commits mailing list