#pragma once // TODO: remove from here and from the project #include #include "memory/freelist.hpp" #include "memory/lazy_gc.hpp" #include "threading/sync/spinlock.hpp" #include "logging/default.hpp" template class SkiplistGC : public LazyGC, lock_t> { public: SkiplistGC() : logger(logging::log->logger("SkiplistGC")) {} // release_ref method should be called by a thread // when the thread finish it job over object // which has to be lazy cleaned // if thread counter becames zero, all objects in the local_freelist // are going to be deleted // the only problem with this approach is that // GC may never be called, but for now we can deal with that void release_ref() { std::vector local_freelist; // take freelist if there is no more threads { auto lock = this->acquire_unique(); assert(this->count > 0); --this->count; if (this->count == 0) { freelist.swap(local_freelist); } } if (local_freelist.size() > 0) { logger.trace("GC started"); logger.trace("Local list size: {}", local_freelist.size()); long long counter = 0; // destroy all elements from local_freelist for (auto element : local_freelist) { if (element->flags.is_marked()) { T::destroy(element); counter++; } } logger.trace("Number of destroyed elements: {}", counter); } } void collect(T *node) { freelist.add(node); } protected: Logger logger; private: FreeList freelist; };