X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Fpool.h;h=165a3aac4bc95606dd0f12b1263c36b43b34e061;hb=fdaa6a151aa6b0022879d282802b2166aec653dc;hp=d604680ae26d7ce875b3e01fe9464fefa9c306d3;hpb=449aab3c465bbbf66d221fac3d7ea559f1720357;p=ardour.git diff --git a/libs/pbd/pbd/pool.h b/libs/pbd/pbd/pool.h index d604680ae2..165a3aac4b 100644 --- a/libs/pbd/pbd/pool.h +++ b/libs/pbd/pbd/pool.h @@ -23,11 +23,15 @@ #include #include -#include +#include -#include +#include "pbd/libpbd_visibility.h" +#include "pbd/ringbuffer.h" -class Pool +/** A pool of data items that can be allocated, read from and written to + * without system memory allocation or locking. + */ +class LIBPBD_API Pool { public: Pool (std::string name, unsigned long item_size, unsigned long nitems); @@ -38,13 +42,15 @@ class Pool std::string name() const { return _name; } - private: - RingBuffer* free_list; + protected: + RingBuffer free_list; ///< a list of pointers to free items within block std::string _name; - void *block; + + private: + void *block; ///< data storage area }; -class SingleAllocMultiReleasePool : public Pool +class LIBPBD_API SingleAllocMultiReleasePool : public Pool { public: SingleAllocMultiReleasePool (std::string name, unsigned long item_size, unsigned long nitems); @@ -54,11 +60,11 @@ class SingleAllocMultiReleasePool : public Pool virtual void release (void *); private: - Glib::Mutex* m_lock; + Glib::Threads::Mutex m_lock; }; -class MultiAllocSingleReleasePool : public Pool +class LIBPBD_API MultiAllocSingleReleasePool : public Pool { public: MultiAllocSingleReleasePool (std::string name, unsigned long item_size, unsigned long nitems); @@ -68,7 +74,67 @@ class MultiAllocSingleReleasePool : public Pool virtual void release (void *); private: - Glib::Mutex* m_lock; + Glib::Threads::Mutex m_lock; +}; + +class LIBPBD_API PerThreadPool; + +/** Management of a per-thread pool of data that is allocated by one thread and + * freed by one other thread. Not safe for use when there is more than 1 + * reader and 1 writer. + * + * This is basically a wrapper around a thread-local storage instance of a + * ringbuffer, made safe for use in the case where multiple threads allocate + * from the ringbuffer and a single thread "frees" the allocations. + * + * Rather than using locks, each thread has its own ringbuffer (and associated + * data), and so it calls alloc(), passes a pointer to the result of the alloc + * to another thread, which later calls push() to "free" it. + */ +class LIBPBD_API CrossThreadPool : public Pool +{ + public: + CrossThreadPool (std::string n, unsigned long isize, unsigned long nitems, PerThreadPool *); + + void* alloc (); + void push (void *); + + PerThreadPool* parent () const { + return _parent; + } + + bool empty (); + + private: + RingBuffer pending; + PerThreadPool* _parent; +}; + +/** A class to manage per-thread pools of memory. One object of this class is instantiated, + * and then it is used to create per-thread pools for 1 or more threads as required. + */ +class LIBPBD_API PerThreadPool +{ + public: + PerThreadPool (); + + const Glib::Threads::Private& key() const { return _key; } + + void create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems); + CrossThreadPool* per_thread_pool (); + + void set_trash (RingBuffer* t); + void add_to_trash (CrossThreadPool *); + + private: + Glib::Threads::Private _key; + std::string _name; + unsigned long _item_size; + unsigned long _nitems; + + /** mutex to protect either changes to the _trash variable, or writes to the RingBuffer */ + Glib::Threads::Mutex _trash_mutex; + RingBuffer* _trash; }; #endif // __qm_pool_h__