/[svn]/linuxsampler/trunk/src/common/Pool.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/Pool.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 271 by schoenebeck, Fri Oct 8 20:51:39 2004 UTC revision 2335 by persson, Sat Mar 17 06:19:01 2012 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 - 2012 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 24 
24  #ifndef __LS_POOL_H__  #ifndef __LS_POOL_H__
25  #define __LS_POOL_H__  #define __LS_POOL_H__
26    
27  #ifndef DEVMODE  #ifdef HAVE_CONFIG_H
28  # include "global.h" // just to check if we should compile in 'DEVMODE'  # include <config.h>
29  #endif  #endif
30    
31  // we just use exceptions for debugging, better not in the final realtime thread !  // we just use exceptions for debugging, better not in the final realtime thread !
32  #ifndef USE_EXCEPTIONS  #ifndef CONFIG_RT_EXCEPTIONS
33  # define USE_EXCEPTIONS 0  # define CONFIG_RT_EXCEPTIONS 0
34  #endif  #endif
35    
36  #if USE_EXCEPTIONS  #if CONFIG_RT_EXCEPTIONS
37  # include <stdexcept>  # include <stdexcept>
38  # include <string>  # include <string>
39    #endif // CONFIG_RT_EXCEPTIONS
40    
41    #if CONFIG_DEVMODE
42    # include <string>
43    # include <iostream>
44  const std::string __err_msg_iterator_invalidated = "Pool/RTList iterator invalidated";  const std::string __err_msg_iterator_invalidated = "Pool/RTList iterator invalidated";
45  #endif // USE_EXCEPTIONS  #endif // CONFIG_DEVMODE
46    
47    const std::string __err_msg_resize_while_in_use = "Pool::resizePool() ERROR: elements still in use!";
48    
49  // just symbol prototyping  // just symbol prototyping
50  template<typename T> class Pool;  template<typename T> class Pool;
# Line 45  template<typename T> class RTList; Line 53  template<typename T> class RTList;
53  template<typename T>  template<typename T>
54  class RTListBase {  class RTListBase {
55      protected:      protected:
56          template<typename _T>          template<typename T1>
57          struct _Node {          struct _Node {
58              _Node<_T>* next;              _Node<T1>* next;
59              _Node<_T>* prev;              _Node<T1>* prev;
60              _T* data;              T1* data;
61              #if DEVMODE              #if CONFIG_DEVMODE
62              RTListBase<_T>* list; // list to which this node currently belongs to              RTListBase<T1>* list; // list to which this node currently belongs to
63              #endif // DEVMODE              #endif // CONFIG_DEVMODE
64    
65              _Node() {              _Node() {
66                  next = NULL;                  next = NULL;
67                  prev = NULL;                  prev = NULL;
68                  data = NULL;                  data = NULL;
69                  #if DEVMODE                  #if CONFIG_DEVMODE
70                  list = NULL;                  list = NULL;
71                  #endif // DEVMODE                  #endif // CONFIG_DEVMODE
72              }              }
73          };          };
74          typedef _Node<T> Node;          typedef _Node<T> Node;
75    
76      public:      public:
77          template<typename _T>          template<typename T1>
78          class _Iterator {          class _Iterator {
79              public:              public:
80                  _Iterator() {                  _Iterator() {
81                      current  = NULL;                      current  = NULL;
82                      fallback = NULL;                      fallback = NULL;
83                      #if DEVMODE                      #if CONFIG_DEVMODE
84                      list = NULL;                      list = NULL;
85                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
86                  }                  }
87    
88                  /// prefix increment op.                  /// prefix increment op.
89                  inline _Iterator& operator++() {                  inline _Iterator& operator++() {
90                      #if DEVMODE                      #if CONFIG_DEVMODE
91                      #if USE_EXCEPTIONS                      if (!isValid()) {
92                      if (!isValid()) throw std::runtime_error(__err_msg_iterator_invalidated);                          #if CONFIG_RT_EXCEPTIONS
93                      #else                          throw std::runtime_error(__err_msg_iterator_invalidated);
94                      if (!isValid()) return *(_Iterator*)NULL; // force segfault if iterator became invalidated                          #else
95                      #endif // USE_EXCEPTIONS                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
96                      #endif // DEVMODE                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated
97                            #endif // CONFIG_RT_EXCEPTIONS
98                        }
99                        #endif // CONFIG_DEVMODE
100                      fallback = current;                      fallback = current;
101                      current  = current->next;                      current  = current->next;
102                      return *this;                      return *this;
# Line 94  class RTListBase { Line 105  class RTListBase {
105                  /// postfix increment op.                  /// postfix increment op.
106                  inline _Iterator operator++(int) {                  inline _Iterator operator++(int) {
107                      _Iterator preval = *this;                      _Iterator preval = *this;
108                      ++*this;                      ++*this; // use prefix operator implementation
109                      return preval;                      return preval;
110                  }                  }
111    
112                  /// prefix decrement op.                  /// prefix decrement op.
113                  inline _Iterator& operator--() {                  inline _Iterator& operator--() {
114                      #if DEVMODE                      #if CONFIG_DEVMODE
115                      #if USE_EXCEPTIONS                      if (!isValid()) {
116                      if (!isValid()) throw std::runtime_error(__err_msg_iterator_invalidated);                          #if CONFIG_RT_EXCEPTIONS
117                      #else                          throw std::runtime_error(__err_msg_iterator_invalidated);
118                      if (!isValid()) return *(_Iterator*)NULL; // force segfault if iterator became invalidated                          #else
119                      #endif // USE_EXCEPTIONS                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
120                      #endif // DEVMODE                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated
121                            #endif // CONFIG_RT_EXCEPTIONS
122                        }
123                        #endif // CONFIG_DEVMODE
124                      fallback = current;                      fallback = current;
125                      current  = current->prev;                      current  = current->prev;
126                      return *this;                      return *this;
# Line 115  class RTListBase { Line 129  class RTListBase {
129                  /// postfix decrement op.                  /// postfix decrement op.
130                  inline _Iterator operator--(int) {                  inline _Iterator operator--(int) {
131                      _Iterator preval = *this;                      _Iterator preval = *this;
132                      --*this;                      --*this; // use prefix operator implementation
133                      return preval;                      return preval;
134                  }                  }
135    
136                  inline _T& operator*() {                  inline T1& operator*() {
137                      #if DEVMODE                      #if CONFIG_DEVMODE
138                      #if USE_EXCEPTIONS                      if (!isValid()) { // if iterator became invalidated
139                      if (isValid()) return *current->data;                          #if CONFIG_RT_EXCEPTIONS
140                      else throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
141                      #else                          #else
142                      return *(isValid() ? current->data : (_T*)NULL); // force segfault if iterator became invalidated                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
143                      #endif // USE_EXCEPTIONS                          return *((T1*)NULL); // force segfault if iterator became invalidated
144                      #else                          #endif // CONFIG_RT_EXCEPTIONS
145                        }
146                        #endif // CONFIG_DEVMODE
147                      return *current->data;                      return *current->data;
148                      #endif // DEVMODE  
149                  }                  }
150    
151                  inline _T* operator->() {                  inline T1* operator->() {
152                      #if DEVMODE                      #if CONFIG_DEVMODE
153                      #if USE_EXCEPTIONS                      if (!isValid()) { // if iterator became invalidated
154                      if (isValid()) return current->data;                          #if CONFIG_RT_EXCEPTIONS
155                      else throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
156                      #else                          #else
157                      return isValid() ? current->data : (_T*)NULL; // force segfault if iterator became invalidated                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
158                      #endif // USE_EXCEPTIONS                          return (T1*)NULL; // force segfault if iterator became invalidated
159                      #else                          #endif // CONFIG_RT_EXCEPTIONS
160                        }
161                        #endif // CONFIG_DEVMODE
162                      return current->data;                      return current->data;
                     #endif // DEVMODE  
163                  }                  }
164    
165                  inline bool operator==(const _Iterator<_T> other) {                  inline bool operator==(const _Iterator<T1> other) {
166                      return current == other.current;                      return current == other.current;
167                  }                  }
168    
169                  inline bool operator!=(const _Iterator<_T> other) {                  inline bool operator!=(const _Iterator<T1> other) {
170                      return current != other.current;                      return current != other.current;
171                  }                  }
172    
# Line 161  class RTListBase { Line 178  class RTListBase {
178                      return !(current && current->data);                      return !(current && current->data);
179                  }                  }
180    
181                  inline _Iterator moveToEndOf(RTListBase<_T>* pDstList) {                  inline _Iterator moveToEndOf(RTListBase<T1>* pDstList) {
182                      detach();                      detach();
183                      pDstList->append(*this);                      pDstList->append(*this);
184                      _Iterator iterOnDstList = _Iterator(current);                      _Iterator iterOnDstList = _Iterator(current);
# Line 169  class RTListBase { Line 186  class RTListBase {
186                      return iterOnDstList;                      return iterOnDstList;
187                  }                  }
188    
189                  inline _Iterator moveToBeginOf(RTListBase<_T>* pDstList) {                  inline _Iterator moveToBeginOf(RTListBase<T1>* pDstList) {
190                      detach();                      detach();
191                      pDstList->prepend(*this);                      pDstList->prepend(*this);
192                      _Iterator iterOnDstList = _Iterator(current);                      _Iterator iterOnDstList = _Iterator(current);
# Line 177  class RTListBase { Line 194  class RTListBase {
194                      return iterOnDstList;                      return iterOnDstList;
195                  }                  }
196    
197                  #if DEVMODE                  #if CONFIG_DEVMODE
198                  inline bool isValid() {                  inline bool isValid() {
199                      return current->list == list;                      return current->list == list;
200                  }                  }
201                  #endif // DEVMODE                  #endif // CONFIG_DEVMODE
202    
203              protected:              protected:
204                  Node* current;                  Node* current;
# Line 190  class RTListBase { Line 207  class RTListBase {
207                      dir_forward,                      dir_forward,
208                      dir_backward                      dir_backward
209                  };                  };
210                  #if DEVMODE                  #if CONFIG_DEVMODE
211                  RTListBase<_T>* list;                  RTListBase<T1>* list;
212                  #endif // DEVMODE                  #endif // CONFIG_DEVMODE
213    
214                  _Iterator(Node* pNode, dir_t direction = dir_forward) {                  _Iterator(Node* pNode, dir_t direction = dir_forward) {
215                      current  = pNode;                      current  = pNode;
216                      fallback = (direction == dir_forward) ? pNode->prev : pNode->next;                      fallback = (direction == dir_forward) ? pNode->prev : pNode->next;
217                      #if DEVMODE                      #if CONFIG_DEVMODE
218                      list = pNode->list;                      list = pNode->list;
219                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
220                  }                  }
221    
222                  inline Node* node() {                  inline Node* node() {
223                      #if DEVMODE                      #if CONFIG_DEVMODE
224                      #if USE_EXCEPTIONS                      #if CONFIG_RT_EXCEPTIONS
225                      if (isValid()) return current;                      if (isValid()) return current;
226                      else throw std::runtime_error(__err_msg_iterator_invalidated);                      else throw std::runtime_error(__err_msg_iterator_invalidated);
227                      #else                      #else
228                      return (isValid()) ? current : (Node*)NULL; // force segfault if iterator became invalidated                      return (isValid()) ? current : (Node*)NULL; // force segfault if iterator became invalidated
229                      #endif // USE_EXCEPTIONS                      #endif // CONFIG_RT_EXCEPTIONS
230                      #else                      #else
231                      return current;                      return current;
232                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
233                  }                  }
234    
235                  inline void detach() {                  inline void detach() {
236                      RTListBase<_T>::detach(*this);                      RTListBase<T1>::detach(*this);
237                  }                  }
238    
239                  friend class RTListBase<_T>;                  friend class RTListBase<T1>;
240                  friend class RTList<_T>;                  friend class RTList<T1>;
241                  friend class Pool<_T>;                  friend class Pool<T1>;
242          };          };
243          typedef _Iterator<T> Iterator;          typedef _Iterator<T> Iterator;
244    
# Line 245  class RTListBase { Line 262  class RTListBase {
262              return _begin.next == &_end;              return _begin.next == &_end;
263          }          }
264    
265            inline int count() {
266                int elements = 0;
267                for (Iterator it = first(); it != end(); ++it) ++elements;
268                return elements;
269            }
270    
271      protected:      protected:
272          Node _begin; // fake node (without data) which represents the begin of the list - not the first element!          Node _begin; // fake node (without data) which represents the begin of the list - not the first element!
273          Node _end;   // fake node (without data) which represents the end of the list - not the last element!          Node _end;   // fake node (without data) which represents the end of the list - not the last element!
274    
275          RTListBase() {          RTListBase() {
276                init();
277            }
278    
279            void init() {
280              // initialize boundary nodes              // initialize boundary nodes
281              _begin.prev = &_begin;              _begin.prev = &_begin;
282              _begin.next = &_end;              _begin.next = &_end;
# Line 257  class RTListBase { Line 284  class RTListBase {
284              _end.next = &_end;              _end.next = &_end;
285              _end.prev = &_begin;              _end.prev = &_begin;
286              _end.data = NULL;              _end.data = NULL;
287              #if DEVMODE              #if CONFIG_DEVMODE
288              _begin.list = this;              _begin.list = this;
289              _end.list   = this;              _end.list   = this;
290              #endif // DEVMODE              #endif // CONFIG_DEVMODE
291          }          }
292    
293          inline void append(Iterator itElement) {          inline void append(Iterator itElement) {
# Line 270  class RTListBase { Line 297  class RTListBase {
297              pNode->prev = last; // if a segfault happens here, then because 'itElement' Iterator became invalidated              pNode->prev = last; // if a segfault happens here, then because 'itElement' Iterator became invalidated
298              pNode->next = &_end;              pNode->next = &_end;
299              _end.prev   = pNode;              _end.prev   = pNode;
300              #if DEVMODE              #if CONFIG_DEVMODE
301              pNode->list = this;              pNode->list = this;
302              #endif // DEVMODE              #endif // CONFIG_DEVMODE
303          }          }
304    
305          inline void append(Iterator itFirst, Iterator itLast) {          inline void append(Iterator itFirst, Iterator itLast) {
# Line 283  class RTListBase { Line 310  class RTListBase {
310              pFirst->prev = last;  // if a segfault happens here, then because 'itFirst' Iterator became invalidated              pFirst->prev = last;  // if a segfault happens here, then because 'itFirst' Iterator became invalidated
311              pLast->next  = &_end; // if a segfault happens here, then because 'itLast' Iterator became invalidated              pLast->next  = &_end; // if a segfault happens here, then because 'itLast' Iterator became invalidated
312              _end.prev    = pLast;              _end.prev    = pLast;
313              #if DEVMODE              #if CONFIG_DEVMODE
314              for (Node* pNode = pFirst; true; pNode = pNode->next) {              for (Node* pNode = pFirst; true; pNode = pNode->next) {
315                  pNode->list = this;                  pNode->list = this;
316                  if (pNode == pLast) break;                  if (pNode == pLast) break;
317              }              }
318              #endif // DEVMODE              #endif // CONFIG_DEVMODE
319          }          }
320    
321          inline void prepend(Iterator itElement) {          inline void prepend(Iterator itElement) {
# Line 298  class RTListBase { Line 325  class RTListBase {
325              pNode->prev = &_begin; // if a segfault happens here, then because 'itElement' Iterator became invalidated              pNode->prev = &_begin; // if a segfault happens here, then because 'itElement' Iterator became invalidated
326              pNode->next = first;              pNode->next = first;
327              first->prev = pNode;              first->prev = pNode;
328              #if DEVMODE              #if CONFIG_DEVMODE
329              pNode->list = this;              pNode->list = this;
330              #endif // DEVMODE              #endif // CONFIG_DEVMODE
331          }          }
332    
333          inline void prepend(Iterator itFirst, Iterator itLast) {          inline void prepend(Iterator itFirst, Iterator itLast) {
# Line 311  class RTListBase { Line 338  class RTListBase {
338              pFirst->prev = &_begin; // if a segfault happens here, then because 'itFirst' Iterator became invalidated              pFirst->prev = &_begin; // if a segfault happens here, then because 'itFirst' Iterator became invalidated
339              pLast->next  = first;   // if a segfault happens here, then because 'itLast' Iterator became invalidated              pLast->next  = first;   // if a segfault happens here, then because 'itLast' Iterator became invalidated
340              first->prev  = pLast;              first->prev  = pLast;
341              #if DEVMODE              #if CONFIG_DEVMODE
342              for (Node* pNode = pFirst; true; pNode = pNode->next) {              for (Node* pNode = pFirst; true; pNode = pNode->next) {
343                  pNode->list = this;                  pNode->list = this;
344                  if (pNode == pLast) break;                  if (pNode == pLast) break;
345              }              }
346              #endif // DEVMODE              #endif // CONFIG_DEVMODE
347          }          }
348    
349          static inline void detach(Iterator itElement) {          static inline void detach(Iterator itElement) {
# Line 334  class RTListBase { Line 361  class RTListBase {
361              next->prev = prev;              next->prev = prev;
362          }          }
363    
364            friend class _Iterator<T>;
365            friend class RTList<T>;
366          friend class Pool<T>;          friend class Pool<T>;
367  };  };
368    
# Line 352  class RTList : public RTListBase<T> { Line 381  class RTList : public RTListBase<T> {
381          RTList(Pool<T>* pPool) : RTListBase<T>::RTListBase() {          RTList(Pool<T>* pPool) : RTListBase<T>::RTListBase() {
382              this->pPool = pPool;              this->pPool = pPool;
383          }          }
384            
385            /**
386             * Copy constructor
387             */
388            RTList(RTList<T>& list) : RTListBase<T>::RTListBase() {
389                this->pPool = list.pPool;
390                Iterator it = list.first();
391                Iterator end = list.end();
392                for(; it != end; ++it) {
393                    if (poolIsEmpty()) break;
394                    *(allocAppend()) = *it;
395                }
396            }
397    
398          virtual ~RTList() {          virtual ~RTList() {
399              clear();              clear();
# Line 364  class RTList : public RTListBase<T> { Line 406  class RTList : public RTListBase<T> {
406          inline Iterator allocAppend() {          inline Iterator allocAppend() {
407              if (pPool->poolIsEmpty()) return RTListBase<T>::begin();              if (pPool->poolIsEmpty()) return RTListBase<T>::begin();
408              Iterator element = pPool->alloc();              Iterator element = pPool->alloc();
409              append(element);              this->append(element);
410              #if DEVMODE              #if CONFIG_DEVMODE
411              element.list = this;              element.list = this;
412              #endif // DEVMODE              #endif // CONFIG_DEVMODE
413              return element;              return element;
414          }          }
415    
# Line 375  class RTList : public RTListBase<T> { Line 417  class RTList : public RTListBase<T> {
417              if (pPool->poolIsEmpty()) return RTListBase<T>::end();              if (pPool->poolIsEmpty()) return RTListBase<T>::end();
418              Iterator element = pPool->alloc();              Iterator element = pPool->alloc();
419              prepend(element);              prepend(element);
420              #if DEVMODE              #if CONFIG_DEVMODE
421              element.list = this;              element.list = this;
422              #endif // DEVMODE              #endif // CONFIG_DEVMODE
423              return element;              return element;
424          }          }
425    
# Line 409  class Pool : public RTList<T> { Line 451  class Pool : public RTList<T> {
451          Node*         nodes;          Node*         nodes;
452          T*            data;          T*            data;
453          RTListBase<T> freelist; // not yet allocated elements          RTListBase<T> freelist; // not yet allocated elements
454            int           poolsize;
455    
456          Pool(int Elements) : RTList<T>::RTList(this) {          Pool(int Elements) : RTList<T>::RTList(this) {
457              data  = new T[Elements];              _init(Elements);
             nodes = new Node[Elements];  
             for (int i = 0; i < Elements; i++) {  
                 nodes[i].data = &data[i];  
                 freelist.append(&nodes[i]);  
             }  
458          }          }
459    
460          virtual ~Pool() {          virtual ~Pool() {
# Line 428  class Pool : public RTList<T> { Line 466  class Pool : public RTList<T> {
466              return freelist.isEmpty();              return freelist.isEmpty();
467          }          }
468    
469            /**
470             * Returns the current size of the pool, that is the amount of
471             * pre-allocated elements from the operating system. It equals the
472             * amount of elements given to the constructor unless resizePool()
473             * is called.
474             *
475             * @see resizePool()
476             */
477            int poolSize() const {
478                return poolsize;
479            }
480    
481            /**
482             * Alters the amount of elements to be pre-allocated from the
483             * operating system for this pool object.
484             *
485             * @e CAUTION: you MUST free all elements in use before calling this
486             * method ( e.g. by calling clear() )! Also make sure that no
487             * references of elements before this call will still be used after this
488             * call, since all elements will be reallocated and their old memory
489             * addresses become invalid!
490             *
491             * @see poolSize()
492             */
493            void resizePool(int Elements) {
494                if (freelist.count() != poolsize) {
495                    #if CONFIG_DEVMODE
496                    throw std::runtime_error(__err_msg_resize_while_in_use);
497                    #else
498                    std::cerr << __err_msg_resize_while_in_use << std::endl << std::flush;
499                    // if we're here something's terribly wrong, but we try to do the best
500                    RTList<T>::clear();
501                    #endif
502                }
503                if (nodes) delete[] nodes;
504                if (data)  delete[] data;
505                freelist.init();
506                RTListBase<T>::init();
507                _init(Elements);
508            }
509    
510      protected:      protected:
511          // caution: assumes pool (that is freelist) is not empty!          // caution: assumes pool (that is freelist) is not empty!
512          inline Iterator alloc() {          inline Iterator alloc() {
# Line 445  class Pool : public RTList<T> { Line 524  class Pool : public RTList<T> {
524          }          }
525    
526          friend class RTList<T>;          friend class RTList<T>;
527    
528        private:
529            void _init(int Elements) {
530                data  = new T[Elements];
531                nodes = new Node[Elements];
532                for (int i = 0; i < Elements; i++) {
533                    nodes[i].data = &data[i];
534                    freelist.append(&nodes[i]);
535                }
536                poolsize = Elements;
537            }
538  };  };
539    
540  #endif // __LS_POOL_H__  #endif // __LS_POOL_H__

Legend:
Removed from v.271  
changed lines
  Added in v.2335

  ViewVC Help
Powered by ViewVC