// Copyright 2024 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MEMORY_SHARED_MEMORY_SAFETY_CHECKER_H_ #define BASE_MEMORY_SHARED_MEMORY_SAFETY_CHECKER_H_ #include #include #include #include "base/containers/span.h" namespace base::subtle { // Constraints on types that can be copied across memory spaces. This is a // non-exhaustive list and further constraints may be added in the future. // `kIsAllowed` is true unless T is known to be dangerous over shared memory. template struct SharedMemorySafetyChecker { // Copying non-trivially-copyable objects across memory spaces is dangerous. // This check isn't a separate specialization because many types that match // other specializations are also trivially copyable, introducing ambiguity. static constexpr bool kIsAllowed = std::is_trivially_copyable_v; }; // Pointers can't be shared across memory spaces. template requires(std::is_pointer_v || std::is_member_pointer_v) struct SharedMemorySafetyChecker { static constexpr bool kIsAllowed = false; }; // Spans can't be shared across memory spaces. template struct SharedMemorySafetyChecker> { static constexpr bool kIsAllowed = false; }; // Atomics are dangerous to share across memory spaces unless they're lock-free. template struct SharedMemorySafetyChecker> { static constexpr bool kIsAllowed = std::atomic::is_always_lock_free && SharedMemorySafetyChecker::kIsAllowed; }; // Each element of an array must itself be safe. Although arrays aren't outright // banned, prefer to use GetMemoryAsSpan for array-like access. template struct SharedMemorySafetyChecker { static constexpr bool kIsAllowed = SharedMemorySafetyChecker::kIsAllowed; }; template struct SharedMemorySafetyChecker> { static constexpr bool kIsAllowed = SharedMemorySafetyChecker::kIsAllowed; }; template concept AllowedOverSharedMemory = SharedMemorySafetyChecker::kIsAllowed; // Convenience alias for atomics that are safe to share across memory spaces. template requires AllowedOverSharedMemory> using SharedAtomic = std::atomic; } // namespace base::subtle #endif // BASE_MEMORY_SHARED_MEMORY_SAFETY_CHECKER_H_