Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:14:33

0001 // Author: Enrico Guiraud, Danilo Piparo CERN  03/2017
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT_RSLOTSTACK
0012 #define ROOT_RSLOTSTACK
0013 
0014 #include <atomic>
0015 #include <vector>
0016 
0017 namespace ROOT {
0018 namespace Internal {
0019 
0020 /// A thread-safe list of N indexes (0 to size - 1).
0021 /// RSlotStack can be used to atomically assign a "processing slot" number to
0022 /// each thread in multi-threaded applications.
0023 /// When there are no more slots available, the thread busy-waits for a slot.
0024 /// This case should be avoided by the scheduler.
0025 class RSlotStack {
0026    struct alignas(8) AtomicWrapper {
0027       std::atomic_bool fAtomic{false};
0028       AtomicWrapper() = default;
0029       ~AtomicWrapper() = default;
0030       AtomicWrapper(const AtomicWrapper &) = delete;
0031       AtomicWrapper &operator=(const AtomicWrapper &) = delete;
0032       AtomicWrapper(AtomicWrapper &&other) { fAtomic = other.fAtomic.load(); }
0033       AtomicWrapper &operator=(AtomicWrapper &&other)
0034       {
0035          fAtomic = other.fAtomic.load();
0036          return *this;
0037       }
0038    };
0039    std::vector<AtomicWrapper> fSlots;
0040 
0041 public:
0042    RSlotStack() = delete;
0043    RSlotStack(unsigned int size);
0044    void ReturnSlot(unsigned int slotNumber);
0045    unsigned int GetSlot();
0046 };
0047 
0048 /// A RAII object to pop and push slot numbers from a RSlotStack object.
0049 /// After construction the slot number is available as the data member fSlot.
0050 struct RSlotStackRAII {
0051    ROOT::Internal::RSlotStack &fSlotStack;
0052    const unsigned int fSlot;
0053    RSlotStackRAII(ROOT::Internal::RSlotStack &slotStack) : fSlotStack(slotStack), fSlot(slotStack.GetSlot()) {}
0054    ~RSlotStackRAII() { fSlotStack.ReturnSlot(fSlot); }
0055 };
0056 
0057 } // namespace Internal
0058 } // namespace ROOT
0059 
0060 #endif