Skip to content

Conversation

@SchrodingerZhu
Copy link
Contributor

@SchrodingerZhu SchrodingerZhu commented Jan 9, 2025

Does not work yet. I need to work out a lot more details. This is for collecting ideas.

snmalloc is already supported in LLVM for windows CRT replacement, we can also use it as an implementation of our allocator:

if(LLVM_INTEGRATED_CRT_ALLOC)

Adding snmalloc will push forward our support on windows/macos easily. It also provides linux target with a modern allocator alternative.

I have made snmalloc buildable with clean C headers in microsoft/snmalloc#722, hence, it can now be used in a way largely similar to scudo standalone allocator.

malloc.cpp.o is already buildable with some ad-hoc fixes, so I think there is no technical obstacle.

Know to work: snmalloc 229c6d04fea5b6b0757be99a2b6394e3aea5d562

git clone https://github.com/microsoft/snmalloc/ export SNMALLOC_DIR=$(realpath snmalloc) pushd snmalloc git checkout 229c6d04fea5b6b0757be99a2b6394e3aea5d562 popd git clone https://github.com/llvm/llvm-project cd llvm-project mkdir build cd build cmake ../runtimes \ -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 
@SchrodingerZhu
Copy link
Contributor Author

cc @mjp41

@SchrodingerZhu SchrodingerZhu force-pushed the snmalloc-2 branch 2 times, most recently from 5551d5a to ddedf1e Compare January 16, 2025 03:41
@github-actions
Copy link

github-actions bot commented Jan 16, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@SchrodingerZhu SchrodingerZhu force-pushed the snmalloc-2 branch 2 times, most recently from f9ace97 to 1382389 Compare January 16, 2025 06:16
@SchrodingerZhu SchrodingerZhu marked this pull request as ready for review January 16, 2025 06:21
@llvmbot llvmbot added the libc label Jan 16, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2025

@llvm/pr-subscribers-libc

Author: Schrodinger ZHU Yifan (SchrodingerZhu)

Changes

Does not work yet. I need to work out a lot more details. This is for collecting ideas.

snmalloc is already supported in LLVM for windows CRT replacement, we can also use it as an implementation of our allocator:

if(LLVM_INTEGRATED_CRT_ALLOC)

Adding snmalloc will push forward our support on windows/macos easily. It also provides linux target with a modern allocator alternative.

I have made snmalloc buildable with clean C headers in microsoft/snmalloc#722, hence, it can now be used in a way largely similar to scudo standalone allocator.

malloc.cpp.o is already buildable with some ad-hoc fixes, so I think there is no technical obstacle.


Full diff: https://github.com/llvm/llvm-project/pull/122284.diff

10 Files Affected:

  • (modified) libc/src/stdlib/CMakeLists.txt (+40-1)
  • (added) libc/src/stdlib/snmalloc/CMakeLists.txt (+119)
  • (added) libc/src/stdlib/snmalloc/aligned_alloc.cpp (+17)
  • (added) libc/src/stdlib/snmalloc/calloc.cpp (+17)
  • (added) libc/src/stdlib/snmalloc/free.cpp (+17)
  • (added) libc/src/stdlib/snmalloc/malloc.cpp (+17)
  • (added) libc/src/stdlib/snmalloc/mallopt.cpp (+13)
  • (added) libc/src/stdlib/snmalloc/override.h (+32)
  • (added) libc/src/stdlib/snmalloc/realloc.cpp (+17)
  • (modified) libc/test/src/stdlib/CMakeLists.txt (+3-1)
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index 40ba9ead9a7ae6..7d0dfd1aa9da4b 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -324,7 +324,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 00000000000000..e360b36f5fb3ad --- /dev/null +++ b/libc/src/stdlib/snmalloc/CMakeLists.txt @@ -0,0 +1,119 @@ +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 + -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} +) + +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 + malloc.cpp + DEPENDS + snmalloc +) + +add_entrypoint_object( + calloc + SRCS + calloc.cpp + DEPENDS + snmalloc + ${SNMALLOC_DEPS} +) + +add_entrypoint_object( + realloc + SRCS + realloc.cpp + DEPENDS + snmalloc + ${SNMALLOC_DEPS} +) + +add_entrypoint_object( + aligned_alloc + SRCS + aligned_alloc.cpp + DEPENDS + snmalloc + ${SNMALLOC_DEPS} +) + +add_entrypoint_object( + free + SRCS + free.cpp + DEPENDS + snmalloc + ${SNMALLOC_DEPS} +) + +add_entrypoint_object( + mallopt + SRCS + mallopt.cpp + DEPENDS + snmalloc + ${SNMALLOC_DEPS} +) diff --git a/libc/src/stdlib/snmalloc/aligned_alloc.cpp b/libc/src/stdlib/snmalloc/aligned_alloc.cpp new file mode 100644 index 00000000000000..ee1d74ca9c778c --- /dev/null +++ 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 new file mode 100644 index 00000000000000..39af67607bf709 --- /dev/null +++ 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 new file mode 100644 index 00000000000000..eb403710fffada --- /dev/null +++ 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 new file mode 100644 index 00000000000000..ab58e63743016a --- /dev/null +++ b/libc/src/stdlib/snmalloc/malloc.cpp @@ -0,0 +1,17 @@ +//===-- 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" + +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 00000000000000..c52d68e3d52230 --- /dev/null +++ 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/override.h b/libc/src/stdlib/snmalloc/override.h new file mode 100644 index 00000000000000..a36a6316790fbd --- /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/src/stdlib/snmalloc/realloc.cpp b/libc/src/stdlib/snmalloc/realloc.cpp new file mode 100644 index 00000000000000..36972e0a2232ec --- /dev/null +++ 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 diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt index 8cc0428632ba39..2346a8bae08f87 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -420,7 +420,9 @@ if(LLVM_LIBC_FULL_BUILD) ) # Only baremetal and GPU has an in-tree 'malloc' implementation. - if(LIBC_TARGET_OS_IS_BAREMETAL OR LIBC_TARGET_OS_IS_GPU) + if(LIBC_TARGET_OS_IS_BAREMETAL + OR LIBC_TARGET_OS_IS_GPU + OR NOT "${LLVM_LIBC_INCLUDE_SNMALLOC}" STREQUAL "") add_libc_test( malloc_test HERMETIC_TEST_ONLY 
@SchrodingerZhu SchrodingerZhu changed the title POC: add snmalloc as an alternative allocator to libc Add snmalloc as an alternative allocator to libc Jan 16, 2025
@SchrodingerZhu SchrodingerZhu changed the title Add snmalloc as an alternative allocator to libc [libc] add snmalloc as an alternative allocator to libc Jan 16, 2025
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there circular dependency among these targets back to malloc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atexit may

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So atexit would only be called inside register_cleanup. This occurs when snmalloc detects this thread's allocator has not been initialised. If this is the case it initializes the allocator. Once initialised it calls register_cleanup, and then it performs the original operation on the allocator.

https://github.com/microsoft/snmalloc/blob/main/src%2Fsnmalloc%2Fmem%2Flocalalloc.h#L146-L148

I'm happy to expand the description of this code if helpful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation! I don't think it is a problem right now, but at some point we should break the circular dependency in our cmake targets, or at least among the subdirectories.

@SchrodingerZhu
Copy link
Contributor Author

SchrodingerZhu commented Jan 18, 2025

LLVM-libc atexit implementation calls malloc to obtain chunks when public packaging mode is enabled, which looks suspicious to me. We should probably change the behavior.

On the other hand, we can also call allocators cleanup hook (_malloc_thread_cleanup) internally since we do have full control of threads and main CRT startup/teardown in hermetic/fullbuild.

@mjp41
Copy link
Contributor

mjp41 commented Jan 18, 2025

LLVM-libc atexit implementation calls malloc to obtain chunks when public packaging mode is enabled, which looks suspicious to me. We should probably change the behavior.

On the other hand, we can also call allocators cleanup hook (_malloc_thread_cleanup) internally since we do have full control of threads and main CRT startup/teardown in hermetic/fullbuild.

So -DSNMALLOC_USE_THREAD_CLEANUP=On will depend on _malloc_thread_cleanup being called, and define that symbol. With that the code that calls pthread stuff and atexit should be removed.

@SchrodingerZhu
Copy link
Contributor Author

SchrodingerZhu commented Jan 19, 2025

@mjp41 Thanks for the suggestion. However, after investigating, I think libc's implementation is quite wrong currently. I am leaning to keep using pthread-style cleanup because it does not need me to inject _malloc_thread_cleanup call into startup and thread init routines.

@lntue @nickdesaulniers

So, right inside startup code, we do a call to atexit, even before call_init_array_callbacks.

 //... // We want the fini array callbacks to be run after other atexit // callbacks are run. So, we register them before running the init // array callbacks as they can potentially register their own atexit // callbacks. atexit(&call_fini_array_callbacks); call_init_array_callbacks(static_cast<int>(app.args->argc), reinterpret_cast<char **>(app.args->argv), reinterpret_cast<char **>(env_ptr)); int retval = main(static_cast<int>(app.args->argc), reinterpret_cast<char **>(app.args->argv), reinterpret_cast<char **>(env_ptr)); exit(retval);

When LIBC_COPT_PUBLIC_PACKAGING=On , this call will invoke malloc via our new operators.

#if defined(LIBC_TARGET_ARCH_IS_GPU) using ExitCallbackList = FixedVector<AtExitUnit, 64>; #elif defined(LIBC_COPT_PUBLIC_PACKAGING) using ExitCallbackList = ReverseOrderBlockStore<AtExitUnit, 32>; #else using ExitCallbackList = FixedVector<AtExitUnit, CALLBACK_LIST_SIZE_FOR_TESTS>; #endif

This is very wrong in the sense that allocator is not even initialized. It is likely that allocators themselves will need to install exiting hooks. I suggest we should use mmapped memory here.

Sorry, I think MUSL is also doing something similar:

https://github.com/bminor/musl/blob/61399d4bd02ae1ec03068445aa7ffe9174466bfd/src/exit/atexit.c#L64C23-L64C29

@SchrodingerZhu
Copy link
Contributor Author

I have updated according to my observations and the discussion above. Please take a look.

@mjp41
Copy link
Contributor

mjp41 commented Jan 19, 2025

I have updated according to my observations and the discussion above. Please take a look.

Looks good from snmalloc's side.

@SchrodingerZhu
Copy link
Contributor Author

A gentle ping~ @lntue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use LIBC_* for newer flag instead of LLVM_LIBC_*

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

Copy link
Member

@nickdesaulniers nickdesaulniers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs docs on how one configures llvm-libc to use snmalloc.

Can you file a bug about the atexit allocation you mention earlier?

@SchrodingerZhu SchrodingerZhu force-pushed the snmalloc-2 branch 2 times, most recently from b58cd1e to 655d5b1 Compare January 26, 2025 12:57
Copy link
Contributor

@lntue lntue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Please wait for @nickdesaulniers. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if LLVM_LIBC_INCLUDE_SCUDO and LLVM_LIBC_INCLUDE_SNMALLOC are used at the same time?

We now have four allocator options usable with the LLVM-libc:

  • snmalloc and scudo, which are stubs that wrap external libraries
  • baremetal malloc, which is a full malloc implementation
  • gpu malloc, which is a set of wrappers using RPCs

I'm planning to lift baremetal malloc out of baremetal in the near future; it isn't all that baremetal specific, since it's based on dlmalloc, which is useable both on embedded and hosted OS systems. With that there will be three allocator options for Linux and friends, so this seems like a good time to introduce a switch-like option (LLVM_LIBC_ALLOCATOR?) to at least make it impossible to simultaneously specify two different allocators.

@nickdesaulniers: if we do this, would we need to keep LLVM_LIBC_INCLUDE_SCUDO for backcompat?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this seems like a good time to introduce a switch-like option

➕ 1️⃣

would we need to keep LLVM_LIBC_INCLUDE_SCUDO for backcompat?

While we are planning have some changes to cmake tied around upstream llvm releases, I'm not sure that we have enough downstream users (that use in tree cmake) at this point that care.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if LLVM_LIBC_INCLUDE_SCUDO and LLVM_LIBC_INCLUDE_SNMALLOC are used at the same time?

That is checked and will explicitly error out in another cmake place. However, I second that having a switch to better. Let me do it in this patch then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching some paper deadlines. Sorry for the delay -- finishing this patch is still of the first priority on my table once I get time.

Copy link
Member

@RossComputerGuy RossComputerGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, looking forward to using this with Nix.

Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, if we're going this route, I think we should just make snmalloc the default allocator and copy it into the tree with a style port. Though I'm not enough of an expert to know the benefits of this versus scudo or why we can't copy SCUDO as well. I just think it's generally problematic that we need to do such weird build magic to get such a fundamental function.

Comment on lines +485 to +488
#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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any way we can get it to work without this?

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some updates, and we should set up some sort of testing for this, but it looks overall fine.

if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
if(LLVM_LIBC_INCLUDE_SCUDO)
if (NOT "${LIBC_INCLUDE_SNMALLOC}" STREQUAL "")
message(STATUS "Including snmalloc as the allocator, source directory: ${LIBC_INCLUDE_SNMALLOC}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be behind the verbose cmake flag

# 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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
# Only baremetal, snmalloc and GPU has an in-tree 'malloc'
# Only baremetal, snmalloc and GPU have an in-tree 'malloc'
Comment on lines 10 to 11
#define LLVM_LIBC_COMMON_H
#define LLVM_LIBC_ERRNO_H
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be updated, the public header macro for _LLVM_LIBC_COMMON_H has changed.

#define LLVM_LIBC_ERRNO_H

// define common macros
#define __BEGIN_C_DECLS namespace LIBC_NAMESPACE {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be LIBC_NAMESPACE_DECL

#define __BEGIN_C_DECLS namespace LIBC_NAMESPACE {
#define __END_C_DECLS \
} \
using namespace LIBC_NAMESPACE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this necessary?

#define __NOEXCEPT

// TODO: define this in stdio.h
#define STDERR_FILENO 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already defined in unistd-macros.h, is it needed here?

@@ -0,0 +1,36 @@
//===-- Macro Override for SnMalloc ---------------------------------------===//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stuff really just makes me thing that we should just copy the code in-tree and port it as the allocator for linux.

@SchrodingerZhu
Copy link
Contributor Author

@jhuber6

So after microsoft/snmalloc#762, we will be able to use pthread_setspecific to handle clean up. There will be no need to use a separate hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

9 participants