1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <new>
10
11#include "include/atomic_support.h"
12
13#if defined(_LIBCPP_ABI_MICROSOFT)
14# define _LIBPCPP_DEFINE_NEW_HANDLER
15#elif defined(LIBCXX_BUILDING_LIBCXXABI)
16// nothing to do, we use the one from libc++abi
17#elif defined(LIBCXXRT)
18# define _LIBPCPP_DEFINE_NEW_HANDLER
19#elif defined(__GLIBCXX__)
20// nothing to do, we use the one from libstdc++/libsupc++
21#else
22# define _LIBPCPP_DEFINE_NEW_HANDLER
23#endif
24
25#if defined(_LIBPCPP_DEFINE_NEW_HANDLER)
26
27static constinit std::new_handler __new_handler = nullptr;
28
29# ifdef _LIBCPP_ABI_VCRUNTIME
30// to avoid including <new.h>
31using _new_h = int(__cdecl*)(size_t);
32extern "C" _new_h __cdecl _set_new_handler(_new_h);
33
34namespace {
35// adapter for _callnewh
36int __cdecl _new_handler_adapter(size_t) {
37 std::__libcpp_atomic_load (&__new_handler)();
38 return 1;
39}
40} // namespace
41# endif
42
43namespace std { // purposefully not versioned
44
45new_handler set_new_handler(new_handler handler) noexcept {
46# ifdef _LIBCPP_ABI_VCRUNTIME
47 auto old = __libcpp_atomic_exchange(&__new_handler, handler);
48 _set_new_handler(handler ? _new_handler_adapter : nullptr);
49 return old;
50# else
51 return __libcpp_atomic_exchange(&__new_handler, handler);
52# endif
53}
54
55new_handler get_new_handler() noexcept { return __libcpp_atomic_load(&__new_handler); }
56
57} // namespace std
58
59#endif // _LIBPCPP_DEFINE_NEW_HANDLER
60