/[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 478 by persson, Sat Mar 19 09:31:46 2005 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 // USE_EXCEPTIONS  #endif // CONFIG_RT_EXCEPTIONS
40    
41  #if DEVMODE  #if CONFIG_DEVMODE
42  const std::string __err_msg_iterator_invalidated = "Pool/RTList iterator invalidated";  # include <string>
43  # include <iostream>  # include <iostream>
44  #endif  const std::string __err_msg_iterator_invalidated = "Pool/RTList iterator invalidated";
45    #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 54  class RTListBase { Line 58  class RTListBase {
58              _Node<T1>* next;              _Node<T1>* next;
59              _Node<T1>* prev;              _Node<T1>* prev;
60              T1* data;              T1* data;
61              #if DEVMODE              #if CONFIG_DEVMODE
62              RTListBase<T1>* 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;
# Line 76  class RTListBase { Line 80  class RTListBase {
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 (!isValid()) {                      if (!isValid()) {
92                          #if USE_EXCEPTIONS                          #if CONFIG_RT_EXCEPTIONS
93                          throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
94                          #else                          #else
95                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
96                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated
97                          #endif // USE_EXCEPTIONS                          #endif // CONFIG_RT_EXCEPTIONS
98                      }                      }
99                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
100                      fallback = current;                      fallback = current;
101                      current  = current->next;                      current  = current->next;
102                      return *this;                      return *this;
# Line 107  class RTListBase { Line 111  class RTListBase {
111    
112                  /// prefix decrement op.                  /// prefix decrement op.
113                  inline _Iterator& operator--() {                  inline _Iterator& operator--() {
114                      #if DEVMODE                                          #if CONFIG_DEVMODE
115                      if (!isValid()) {                      if (!isValid()) {
116                          #if USE_EXCEPTIONS                          #if CONFIG_RT_EXCEPTIONS
117                          throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
118                          #else                          #else
119                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
120                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated                          return *(_Iterator*)NULL; // force segfault if iterator became invalidated
121                          #endif // USE_EXCEPTIONS                          #endif // CONFIG_RT_EXCEPTIONS
122                      }                                          }
123                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
124                      fallback = current;                      fallback = current;
125                      current  = current->prev;                      current  = current->prev;
126                      return *this;                      return *this;
# Line 130  class RTListBase { Line 134  class RTListBase {
134                  }                  }
135    
136                  inline T1& operator*() {                  inline T1& operator*() {
137                      #if DEVMODE                                          #if CONFIG_DEVMODE
138                      if (!isValid()) { // if iterator became invalidated                      if (!isValid()) { // if iterator became invalidated
139                          #if USE_EXCEPTIONS                          #if CONFIG_RT_EXCEPTIONS
140                          throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
141                          #else                          #else
142                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
143                          return *((T1*)NULL); // force segfault if iterator became invalidated                          return *((T1*)NULL); // force segfault if iterator became invalidated
144                          #endif // USE_EXCEPTIONS                          #endif // CONFIG_RT_EXCEPTIONS
145                      }                      }
146                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
147                      return *current->data;                      return *current->data;
148                        
149                  }                  }
150    
151                  inline T1* operator->() {                  inline T1* operator->() {
152                      #if DEVMODE                      #if CONFIG_DEVMODE
153                      if (!isValid()) { // if iterator became invalidated                      if (!isValid()) { // if iterator became invalidated
154                          #if USE_EXCEPTIONS                          #if CONFIG_RT_EXCEPTIONS
155                          throw std::runtime_error(__err_msg_iterator_invalidated);                          throw std::runtime_error(__err_msg_iterator_invalidated);
156                          #else                          #else
157                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;                          std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
158                          return (T1*)NULL; // force segfault if iterator became invalidated                          return (T1*)NULL; // force segfault if iterator became invalidated
159                          #endif // USE_EXCEPTIONS                          #endif // CONFIG_RT_EXCEPTIONS
160                      }                      }
161                      #endif // DEVMODE                      #endif // CONFIG_DEVMODE
162                      return current->data;                                          return current->data;
163                  }                  }
164    
165                  inline bool operator==(const _Iterator<T1> other) {                  inline bool operator==(const _Iterator<T1> other) {
# Line 190  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 203  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<T1>* 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() {
# Line 258  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 270  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 283  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 296  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 311  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 324  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 367  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 379  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 390  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 424  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 443  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 460  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.478  
changed lines
  Added in v.2335

  ViewVC Help
Powered by ViewVC