diff --git a/src/snmalloc/ds/flaglock.h b/src/snmalloc/ds/flaglock.h index 5fbbf0a..4a539e6 100644 --- a/src/snmalloc/ds/flaglock.h +++ b/src/snmalloc/ds/flaglock.h @@ -1,6 +1,7 @@ #pragma once #include "../aal/aal.h" +#include "../pal/pal.h" #include #include @@ -14,6 +15,8 @@ namespace snmalloc */ struct DebugFlagWord { + using ThreadIdentity = DefaultPal::ThreadIdentity; + /** * @brief flag * The underlying atomic field. @@ -32,7 +35,7 @@ namespace snmalloc */ void set_owner() { - SNMALLOC_ASSERT(nullptr == owner); + SNMALLOC_ASSERT(ThreadIdentity() == owner); owner = get_thread_identity(); } @@ -43,7 +46,7 @@ namespace snmalloc void clear_owner() { SNMALLOC_ASSERT(get_thread_identity() == owner); - owner = nullptr; + owner = ThreadIdentity(); } /** @@ -56,24 +59,19 @@ namespace snmalloc } private: - using ThreadIdentity = int const*; - /** * @brief owner - * We use a pointer to TLS field as the thread identity. - * std::thread::id can be another solution but it does not - * support `constexpr` initialisation on some platforms. + * We use the Pal to provide the ThreadIdentity. */ - std::atomic owner = nullptr; + std::atomic owner = ThreadIdentity(); /** * @brief get_thread_identity * @return The identity of current thread. */ - inline ThreadIdentity get_thread_identity() + static ThreadIdentity get_thread_identity() { - static thread_local int SNMALLOC_THREAD_IDENTITY = 0; - return &SNMALLOC_THREAD_IDENTITY; + return DefaultPal::get_tid(); } }; diff --git a/src/snmalloc/pal/pal.h b/src/snmalloc/pal/pal.h index a8ac8a7..31b846d 100644 --- a/src/snmalloc/pal/pal.h +++ b/src/snmalloc/pal/pal.h @@ -173,23 +173,12 @@ namespace snmalloc DefaultPal::error(msg.get_message()); } - static inline size_t get_tid() - { - static thread_local size_t tid{0}; - static std::atomic tid_source{1}; - - if (tid == 0) - { - tid = tid_source++; - } - return tid; - } - template inline void message(Args... args) { MessageBuilder msg{std::forward(args)...}; - MessageBuilder msg_tid{"{}: {}", get_tid(), msg.get_message()}; + MessageBuilder msg_tid{ + "{}: {}", DefaultPal::get_tid(), msg.get_message()}; DefaultPal::message(msg_tid.get_message()); } } // namespace snmalloc diff --git a/src/snmalloc/pal/pal_concept.h b/src/snmalloc/pal/pal_concept.h index 78270f2..789a00b 100644 --- a/src/snmalloc/pal/pal_concept.h +++ b/src/snmalloc/pal/pal_concept.h @@ -76,6 +76,20 @@ namespace snmalloc noexcept->ConceptSame; }; + /** + * The Pal must provide a thread id for debugging. It should not return + * the default value of ThreadIdentity, as that is used as not an tid in some + * places. + */ + template + concept ConceptPAL_tid = requires() + { + { + PAL::get_tid() + } + noexcept->ConceptSame; + }; + /** * Absent any feature flags, the PAL must support a crude primitive allocator */ @@ -138,7 +152,7 @@ namespace snmalloc template concept ConceptPAL = ConceptPAL_static_features&& ConceptPAL_static_sizes&& ConceptPAL_error&& - ConceptPAL_memops && + ConceptPAL_memops&& ConceptPAL_tid && (!pal_supports || ConceptPAL_get_entropy64< PAL>)&&(!pal_supports || diff --git a/src/snmalloc/pal/pal_open_enclave.h b/src/snmalloc/pal/pal_open_enclave.h index 276af82..be0f141 100644 --- a/src/snmalloc/pal/pal_open_enclave.h +++ b/src/snmalloc/pal/pal_open_enclave.h @@ -1,6 +1,7 @@ #pragma once #include "pal_noalloc.h" +#include "pal_tid_default.h" #ifdef OPEN_ENCLAVE extern "C" void* oe_memset_s(void* p, size_t p_size, int c, size_t size); @@ -25,7 +26,7 @@ namespace snmalloc using OpenEnclaveBasePAL = PALNoAlloc; - class PALOpenEnclave : public OpenEnclaveBasePAL + class PALOpenEnclave : public OpenEnclaveBasePAL, public PalTidDefault { public: /** diff --git a/src/snmalloc/pal/pal_posix.h b/src/snmalloc/pal/pal_posix.h index 58b3c1f..8ad7995 100644 --- a/src/snmalloc/pal/pal_posix.h +++ b/src/snmalloc/pal/pal_posix.h @@ -1,6 +1,7 @@ #pragma once #include "../aal/aal.h" +#include "pal_tid_default.h" #include "pal_timer_default.h" #if defined(SNMALLOC_BACKTRACE_HEADER) # include SNMALLOC_BACKTRACE_HEADER @@ -38,7 +39,8 @@ namespace snmalloc * working when an early-malloc error appears. */ template - class PALPOSIX : public PalTimerDefaultImpl> + class PALPOSIX : public PalTimerDefaultImpl>, + public PalTidDefault { /** * Helper class to access the `default_mmap_flags` field of `OS` if one diff --git a/src/snmalloc/pal/pal_tid_default.h b/src/snmalloc/pal/pal_tid_default.h new file mode 100644 index 0000000..678af98 --- /dev/null +++ b/src/snmalloc/pal/pal_tid_default.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace snmalloc +{ + class PalTidDefault + { + public: + using ThreadIdentity = size_t; + + /** + * @brief Get the an id for the current thread. + * + * @return the thread id, this should never be the default of + * ThreadIdentity. Callers can assume it is a non-default value. + */ + static inline ThreadIdentity get_tid() noexcept + { + static thread_local size_t tid{0}; + static std::atomic tid_source{0}; + + if (tid == 0) + { + tid = ++tid_source; + } + return tid; + } + }; +} // namespace snmalloc \ No newline at end of file diff --git a/src/snmalloc/pal/pal_windows.h b/src/snmalloc/pal/pal_windows.h index 2d6f822..2ab0bfc 100644 --- a/src/snmalloc/pal/pal_windows.h +++ b/src/snmalloc/pal/pal_windows.h @@ -1,6 +1,7 @@ #pragma once #include "../aal/aal.h" +#include "pal_tid_default.h" #include "pal_timer_default.h" #ifdef _WIN32 @@ -26,7 +27,8 @@ namespace snmalloc { - class PALWindows : public PalTimerDefaultImpl + class PALWindows : public PalTimerDefaultImpl, + public PalTidDefault { /** * A flag indicating that we have tried to register for low-memory