~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/pbd/pbd/pool.h

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 1998-99 Paul Barton-Davis
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
*/
 
19
 
 
20
#ifndef __qm_pool_h__
 
21
#define __qm_pool_h__
 
22
 
 
23
#include <vector>
 
24
#include <string>
 
25
 
 
26
#include <glibmm/threads.h>
 
27
 
 
28
#include "pbd/ringbuffer.h"
 
29
 
 
30
/** A pool of data items that can be allocated, read from and written to
 
31
 *  without system memory allocation or locking.
 
32
 */
 
33
class Pool 
 
34
{
 
35
  public:
 
36
        Pool (std::string name, unsigned long item_size, unsigned long nitems);
 
37
        virtual ~Pool ();
 
38
 
 
39
        virtual void *alloc ();
 
40
        virtual void release (void *);
 
41
        
 
42
        std::string name() const { return _name; }
 
43
 
 
44
  protected:
 
45
        RingBuffer<void*> free_list; ///< a list of pointers to free items within block
 
46
        std::string _name;
 
47
 
 
48
  private:
 
49
        void *block; ///< data storage area
 
50
};
 
51
 
 
52
class SingleAllocMultiReleasePool : public Pool
 
53
{
 
54
  public:
 
55
        SingleAllocMultiReleasePool (std::string name, unsigned long item_size, unsigned long nitems);
 
56
        ~SingleAllocMultiReleasePool ();
 
57
 
 
58
        virtual void *alloc ();
 
59
        virtual void release (void *);
 
60
 
 
61
  private:
 
62
        Glib::Threads::Mutex m_lock;
 
63
};
 
64
 
 
65
 
 
66
class MultiAllocSingleReleasePool : public Pool
 
67
{
 
68
  public:
 
69
        MultiAllocSingleReleasePool (std::string name, unsigned long item_size, unsigned long nitems);
 
70
        ~MultiAllocSingleReleasePool ();
 
71
 
 
72
        virtual void *alloc ();
 
73
        virtual void release (void *);
 
74
 
 
75
  private:
 
76
        Glib::Threads::Mutex m_lock;
 
77
};
 
78
 
 
79
class PerThreadPool;
 
80
 
 
81
/** Management of a per-thread pool of data that is allocated by one thread and
 
82
 *  freed by one other thread. Not safe for use when there is more than 1
 
83
 *  reader and 1 writer. 
 
84
 *
 
85
 *  This is basically a wrapper around a thread-local storage instance of a 
 
86
 *  ringbuffer, made safe for use in the case where multiple threads allocate
 
87
 *  from the ringbuffer and a single thread "frees" the allocations.
 
88
 * 
 
89
 *  Rather than using locks, each thread has its own ringbuffer (and associated
 
90
 *  data), and so it calls alloc(), passes a pointer to the result of the alloc
 
91
 *  to another thread, which later calls push() to "free" it. 
 
92
 */
 
93
class CrossThreadPool : public Pool
 
94
{
 
95
  public:
 
96
        CrossThreadPool (std::string n, unsigned long isize, unsigned long nitems, PerThreadPool *);
 
97
 
 
98
        void* alloc ();
 
99
        void push (void *);
 
100
 
 
101
        PerThreadPool* parent () const {
 
102
                return _parent;
 
103
        }
 
104
 
 
105
        bool empty ();
 
106
        
 
107
  private:
 
108
        RingBuffer<void*> pending;
 
109
        PerThreadPool* _parent;
 
110
};
 
111
 
 
112
/** A class to manage per-thread pools of memory.  One object of this class is instantiated,
 
113
 *  and then it is used to create per-thread pools for 1 or more threads as required.
 
114
 */
 
115
class PerThreadPool
 
116
{
 
117
  public:
 
118
        PerThreadPool ();
 
119
 
 
120
        const Glib::Threads::Private<CrossThreadPool>& key() const { return _key; }
 
121
 
 
122
        void  create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems);
 
123
        CrossThreadPool* per_thread_pool ();
 
124
 
 
125
        void set_trash (RingBuffer<CrossThreadPool*>* t);
 
126
        void add_to_trash (CrossThreadPool *);
 
127
 
 
128
  private:
 
129
        Glib::Threads::Private<CrossThreadPool> _key;
 
130
        std::string _name;
 
131
        unsigned long _item_size;
 
132
        unsigned long _nitems;
 
133
 
 
134
        /** mutex to protect either changes to the _trash variable, or writes to the RingBuffer */
 
135
        Glib::Threads::Mutex _trash_mutex;
 
136
        RingBuffer<CrossThreadPool*>* _trash;
 
137
};
 
138
 
 
139
#endif // __qm_pool_h__