options.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //===-- options.h -----------------------------------------------*- C++ -*-===//
  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. #ifndef SCUDO_OPTIONS_H_
  9. #define SCUDO_OPTIONS_H_
  10. #include "atomic_helpers.h"
  11. #include "common.h"
  12. #include "memtag.h"
  13. namespace scudo {
  14. enum class OptionBit {
  15. MayReturnNull,
  16. FillContents0of2,
  17. FillContents1of2,
  18. DeallocTypeMismatch,
  19. DeleteSizeMismatch,
  20. TrackAllocationStacks,
  21. UseOddEvenTags,
  22. UseMemoryTagging,
  23. AddLargeAllocationSlack,
  24. };
  25. struct Options {
  26. u32 Val;
  27. bool get(OptionBit Opt) const { return Val & (1U << static_cast<u32>(Opt)); }
  28. FillContentsMode getFillContentsMode() const {
  29. return static_cast<FillContentsMode>(
  30. (Val >> static_cast<u32>(OptionBit::FillContents0of2)) & 3);
  31. }
  32. };
  33. template <typename Config> bool useMemoryTagging(Options Options) {
  34. return allocatorSupportsMemoryTagging<Config>() &&
  35. Options.get(OptionBit::UseMemoryTagging);
  36. }
  37. struct AtomicOptions {
  38. atomic_u32 Val = {};
  39. Options load() const { return Options{atomic_load_relaxed(&Val)}; }
  40. void clear(OptionBit Opt) {
  41. atomic_fetch_and(&Val, ~(1U << static_cast<u32>(Opt)),
  42. memory_order_relaxed);
  43. }
  44. void set(OptionBit Opt) {
  45. atomic_fetch_or(&Val, 1U << static_cast<u32>(Opt), memory_order_relaxed);
  46. }
  47. void setFillContentsMode(FillContentsMode FillContents) {
  48. u32 Opts = atomic_load_relaxed(&Val), NewOpts;
  49. do {
  50. NewOpts = Opts;
  51. NewOpts &= ~(3U << static_cast<u32>(OptionBit::FillContents0of2));
  52. NewOpts |= static_cast<u32>(FillContents)
  53. << static_cast<u32>(OptionBit::FillContents0of2);
  54. } while (!atomic_compare_exchange_strong(&Val, &Opts, NewOpts,
  55. memory_order_relaxed));
  56. }
  57. };
  58. } // namespace scudo
  59. #endif // SCUDO_OPTIONS_H_