free_list.h 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #pragma once
  2. #include "public.h"
  3. #include <atomic>
  4. namespace NYT {
  5. ////////////////////////////////////////////////////////////////////////////////
  6. template <class T>
  7. struct TFreeListItemBase
  8. {
  9. std::atomic<T*> Next = nullptr;
  10. };
  11. using TAtomicUint128 = volatile unsigned __int128 __attribute__((aligned(16)));
  12. template <class TItem>
  13. class TFreeList
  14. {
  15. private:
  16. struct THead
  17. {
  18. std::atomic<TItem*> Pointer = nullptr;
  19. std::atomic<size_t> Epoch = 0;
  20. THead() = default;
  21. explicit THead(TItem* pointer);
  22. };
  23. union
  24. {
  25. THead Head_;
  26. TAtomicUint128 AtomicHead_;
  27. };
  28. // Avoid false sharing.
  29. char Padding[CacheLineSize - sizeof(TAtomicUint128)];
  30. public:
  31. TFreeList();
  32. TFreeList(TFreeList&& other);
  33. ~TFreeList();
  34. template <class TPredicate>
  35. bool PutIf(TItem* head, TItem* tail, TPredicate predicate);
  36. void Put(TItem* head, TItem* tail);
  37. void Put(TItem* item);
  38. TItem* Extract();
  39. TItem* ExtractAll();
  40. bool IsEmpty() const;
  41. void Append(TFreeList& other);
  42. };
  43. ////////////////////////////////////////////////////////////////////////////////
  44. } // namespace NYT
  45. #define FREE_LIST_INL_H_
  46. #include "free_list-inl.h"
  47. #undef FREE_LIST_INL_H_