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

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

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

revision 267 by schoenebeck, Mon Sep 20 00:20:13 2004 UTC revision 268 by capela, Thu Oct 7 22:20:20 2004 UTC
# Line 81  Line 81 
81    
82  template<class T> class RTELMemoryPool;  template<class T> class RTELMemoryPool;
83    
84    /**
85     * RTEList::Node contains the next and prev pointers needed to manage
86     * the free element list, and anext, aprev needed to manage the list
87     * of allocated elements. This list is handy for the routines that make
88     * use of RTELMemoryPool because the list of elements can be traversed without
89     * building a separate list outside RTELMemoryPool
90     */
91    template<class T>
92    class RTELNode {
93            public:
94                    RTELNode<T>* next;
95                    RTELNode<T>* prev;
96                    RTELNode<T>* anext;
97                    RTELNode<T>* aprev;
98                    T data;
99                    RTELNode() {}
100    };
101    
102  template<class T>  template<class T>
103  class RTEList {  class RTEList {
     public:  
         /**  
          * RTEList::Node contains the next and prev pointers needed to manage  
          * the free element list, and anext, aprev needed to manage the list  
          * of allocated elements. This list is handy for the routines that make  
          * use of RTELMemoryPool because the list of elements can be traversed without  
          * building a separate list outside RTELMemoryPool  
          */  
         template<class _T>  
         class Node {  
             public:  
                 Node<_T>* next;  
                 Node<_T>* prev;  
                 Node<_T>* anext;  
                 Node<_T>* aprev;  
                 _T data;  
                 Node() {}  
         };  
104      protected:      protected:
105          Node<T>  firstnode;          RTELNode<T>  firstnode;
106          Node<T>  lastnode;          RTELNode<T>  lastnode;
107          Node<T>* acurrentnode;          RTELNode<T>* acurrentnode;
108          int   free_offset;          int   free_offset;
109          RTELMemoryPool<T>* pPool;          RTELMemoryPool<T>* pPool;
110    
111          inline void move(Node<T>* pNode, RTEList<T>* pDstList) {          inline void move(RTELNode<T>* pNode, RTEList<T>* pDstList) {
112              // remove element from this list              // remove element from this list
113              RTEList<T>::Node<T>* prev = pNode->aprev;              RTELNode<T>* prev = pNode->aprev;
114              RTEList<T>::Node<T>* next = pNode->anext;              RTELNode<T>* next = pNode->anext;
115              prev->anext = next;              prev->anext = next;
116              next->aprev = prev;              next->aprev = prev;
117    
118              // add element to destination list              // add element to destination list
119              Node<T>* last            = pDstList->lastnode.aprev;              RTELNode<T>* last         = pDstList->lastnode.aprev;
120              last->anext              = pNode;              last->anext              = pNode;
121              pNode->anext             = &pDstList->lastnode;              pNode->anext             = &pDstList->lastnode;
122              pDstList->lastnode.aprev = pNode;              pDstList->lastnode.aprev = pNode;
# Line 124  class RTEList { Line 124  class RTEList {
124          }          }
125    
126          friend class RTELMemoryPool<T>;          friend class RTELMemoryPool<T>;
127    
128      public:      public:
129          /**          /**
130           * Constructor           * Constructor
# Line 209  class RTEList { Line 210  class RTEList {
210              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)
211              node -= free_offset;              node -= free_offset;
212              // select the node              // select the node
213              acurrentnode = (Node<T>*) node;              acurrentnode = (RTELNode<T>*) node;
214          }          }
215    
216          /**          /**
# Line 222  class RTEList { Line 223  class RTEList {
223          inline T* move(RTEList<T>* pDstList) {          inline T* move(RTEList<T>* pDstList) {
224              // if there's a valid element selected              // if there's a valid element selected
225              if (acurrentnode != &firstnode && acurrentnode != &lastnode) {              if (acurrentnode != &firstnode && acurrentnode != &lastnode) {
226                  Node<T>* pNode = acurrentnode;                  RTELNode<T>* pNode = acurrentnode;
227                  acurrentnode   = acurrentnode->aprev; // select previous element                  acurrentnode      = acurrentnode->aprev; // select previous element
228                  move(pNode, pDstList); // move element's node                  move(pNode, pDstList); // move element's node
229                  return &pNode->data;                  return &pNode->data;
230              }              }
# Line 241  class RTEList { Line 242  class RTEList {
242              char* cNode = (char*) pElement;              char* cNode = (char*) pElement;
243              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)
244              cNode -= free_offset;              cNode -= free_offset;
245              Node<T>* pNode = (Node<T>*) cNode;              RTELNode<T>* pNode = (RTELNode<T>*) cNode;
246    
247              // if the node is selected, select previous element              // if the node is selected, select previous element
248              if (acurrentnode == pNode) acurrentnode = acurrentnode->aprev;              if (acurrentnode == pNode) acurrentnode = acurrentnode->aprev;
# Line 313  class RTEList { Line 314  class RTEList {
314  template<class T>  template<class T>
315  class RTELMemoryPool : public RTEList<T> {  class RTELMemoryPool : public RTEList<T> {
316      protected:      protected:
317          RTEList<T>::Node<T>* currentnode;          RTELNode<T>* currentnode;
318    
319          // array that contains the elements:          // array that contains the elements:
320          // each list element is made of list header (prev,next) and the data          // each list element is made of list header (prev,next) and the data
321          // of type T          // of type T
322          RTEList<T>::Node<T>* memory_pool;          RTELNode<T>* memory_pool;
323    
324          /**          /**
325           * Allocate one element of the memory pool           * Allocate one element of the memory pool
# Line 329  class RTELMemoryPool : public RTEList<T> Line 330  class RTELMemoryPool : public RTEList<T>
330           */           */
331          inline T* alloc_append(RTEList<T>* rtelist) {          inline T* alloc_append(RTEList<T>* rtelist) {
332              // get the first element              // get the first element
333              currentnode = firstnode.next;              currentnode = this->firstnode.next;
334              // element->next points to itself which means last element              // element->next points to itself which means last element
335              // return NULL to signal end of list              // return NULL to signal end of list
336              if (currentnode->next == currentnode) return NULL;              if (currentnode->next == currentnode) return NULL;
337    
338              // now remove the element from the freelist              // now remove the element from the freelist
339              RTEList<T>::Node<T>* prevelem = currentnode->prev;              RTELNode<T>* prevelem = currentnode->prev;
340              RTEList<T>::Node<T>* nextelem = currentnode->next;              RTELNode<T>* nextelem = currentnode->next;
341              prevelem->next = nextelem;              prevelem->next = nextelem;
342              nextelem->prev = prevelem;              nextelem->prev = prevelem;
343    
344              // append the element to the external rtelist              // append the element to the external rtelist
345              RTEList<T>::Node<T>* el_lastnode = (RTEList<T>::Node<T>*) &rtelist->lastnode;              RTELNode<T>* el_lastnode = (RTELNode<T>*) &rtelist->lastnode;
346              RTEList<T>::Node<T>* last        = el_lastnode->aprev;              RTELNode<T>* last        = el_lastnode->aprev;
347    
348              last->anext        = currentnode;              last->anext        = currentnode;
349              currentnode->anext = el_lastnode;              currentnode->anext = el_lastnode;
# Line 359  class RTELMemoryPool : public RTEList<T> Line 360  class RTELMemoryPool : public RTEList<T>
360           * beginning of the list           * beginning of the list
361           */           */
362          inline T* alloc_prepend(RTEList<T>* rtelist) {          inline T* alloc_prepend(RTEList<T>* rtelist) {
363              RTEList<T>::Node<T>* prevelem;              RTELNode<T>* prevelem;
364              RTEList<T>::Node<T>* nextelem;              RTELNode<T>* nextelem;
365              // get the first element              // get the first element
366              currentnode = firstnode.next;              currentnode = this->firstnode.next;
367              // element->next points to itself which means last element              // element->next points to itself which means last element
368              // return NULL to signal end of list              // return NULL to signal end of list
369              if (currentnode->next == currentnode) return NULL;              if (currentnode->next == currentnode) return NULL;
# Line 374  class RTELMemoryPool : public RTEList<T> Line 375  class RTELMemoryPool : public RTEList<T>
375              nextelem->prev = prevelem;              nextelem->prev = prevelem;
376    
377              // prepend the element to the external rtelist              // prepend the element to the external rtelist
378              RTEList<T>::Node<T>* el_firstnode = (RTEList<T>::Node<T>*) &rtelist->firstnode;              RTELNode<T>* el_firstnode = (RTELNode<T>*) &rtelist->firstnode;
379              RTEList<T>::Node<T>* first        = el_firstnode->anext;              RTELNode<T>* first        = el_firstnode->anext;
380    
381              currentnode->anext  = first;              currentnode->anext  = first;
382              currentnode->aprev  = el_firstnode;              currentnode->aprev  = el_firstnode;
# Line 386  class RTELMemoryPool : public RTEList<T> Line 387  class RTELMemoryPool : public RTEList<T>
387              return &currentnode->data;              return &currentnode->data;
388          }          }
389    
390          inline void append(RTEList<T>::Node<T>* elem) {          inline void append(RTELNode<T>* elem) {
391              RTEList<T>::Node<T>* last = lastnode.prev;              RTELNode<T>* last = this->lastnode.prev;
392    
393              last->next    = elem;              last->next    = elem;
394              elem->next    = &lastnode;              elem->next    = &(this->lastnode);
395              lastnode.prev = elem;              this->lastnode.prev = elem;
396              elem->prev    = last;              elem->prev    = last;
397          }          }
398    
399          inline void prepend(RTEList<T>::Node<T>* elem) {          inline void prepend(RTELNode<T>* elem) {
400              RTEList<T>::Node<T>* first = firstnode.next;              RTELNode<T>* first = this->firstnode.next;
401    
402              elem->next     = first;              elem->next     = first;
403              elem->prev     = &firstnode;              elem->prev     = &(this->firstnode);
404              firstnode.next = elem;              this->firstnode.next = elem;
405              first->prev    = elem;              first->prev    = elem;
406          }          }
407    
# Line 414  class RTELMemoryPool : public RTEList<T> Line 415  class RTELMemoryPool : public RTEList<T>
415           */           */
416          RTELMemoryPool(int numelements) : RTEList<T>::RTEList(this) {          RTELMemoryPool(int numelements) : RTEList<T>::RTEList(this) {
417              // initialize freelist listnode and lastnode pointers              // initialize freelist listnode and lastnode pointers
418              firstnode.prev = &firstnode;              this->firstnode.prev = &(this->firstnode);
419              firstnode.next = &lastnode;              this->firstnode.next = &(this->lastnode);
420              lastnode.next  = &lastnode;              this->lastnode.next  = &(this->lastnode);
421              lastnode.prev  = &firstnode;              this->lastnode.prev  = &(this->firstnode);
422    
423              currentnode = &lastnode;              currentnode = &(this->lastnode);
424    
425              // initialize alloclist listnode and lastnode pointers              // initialize alloclist listnode and lastnode pointers
426              firstnode.aprev = &firstnode;              this->firstnode.aprev = &(this->firstnode);
427              firstnode.anext = &lastnode;              this->firstnode.anext = &(this->lastnode);
428              lastnode.anext  = &lastnode;              this->lastnode.anext  = &(this->lastnode);
429              lastnode.aprev  = &firstnode;              this->lastnode.aprev  = &(this->firstnode);
430    
431    
432              memory_pool = new RTEList<T>::Node<T>[numelements];              memory_pool = new RTELNode<T>[numelements];
433    
434              for (int i = 0; i < numelements; i++) {              for (int i = 0; i < numelements; i++) {
435                  append(&memory_pool[i]);                  append(&memory_pool[i]);
# Line 443  class RTELMemoryPool : public RTEList<T> Line 444  class RTELMemoryPool : public RTEList<T>
444           * Returns true if no more element can be allocated.           * Returns true if no more element can be allocated.
445           */           */
446          inline bool pool_is_empty() {          inline bool pool_is_empty() {
447              RTEList<T>::Node<T>* nextnode = firstnode.next;              RTELNode<T>* nextnode = this->firstnode.next;
448              return (nextnode->next == nextnode);              return (nextnode->next == nextnode);
449          }          }
450    
# Line 456  class RTELMemoryPool : public RTEList<T> Line 457  class RTELMemoryPool : public RTEList<T>
457           */           */
458          inline T* alloc() {          inline T* alloc() {
459              // get the first element              // get the first element
460              currentnode = firstnode.next;              currentnode = this->firstnode.next;
461              // element->next points to itself which means last element              // element->next points to itself which means last element
462              // return NULL to signal end of list              // return NULL to signal end of list
463              if (currentnode->next == currentnode) return NULL;              if (currentnode->next == currentnode) return NULL;
464    
465              // now remove the element from the freelist              // now remove the element from the freelist
466              RTEList<T>::Node<T>* prevelem = currentnode->prev;              RTELNode<T>* prevelem = currentnode->prev;
467              RTEList<T>::Node<T>* nextelem = currentnode->next;              RTELNode<T>* nextelem = currentnode->next;
468              prevelem->next = nextelem;              prevelem->next = nextelem;
469              nextelem->prev = prevelem;              nextelem->prev = prevelem;
470    
471              // append the element to the alloc list              // append the element to the alloc list
472              RTEList<T>::Node<T>* last = lastnode.aprev;              RTELNode<T>* last = this->lastnode.aprev;
473              last->anext        = currentnode;              last->anext        = currentnode;
474              currentnode->anext = &lastnode;              currentnode->anext = &(this->lastnode);
475              lastnode.aprev     = currentnode;              this->lastnode.aprev = currentnode;
476              currentnode->aprev = last;              currentnode->aprev = last;
477    
478              // finally return the allocated elment              // finally return the allocated elment
# Line 482  class RTELMemoryPool : public RTEList<T> Line 483  class RTELMemoryPool : public RTEList<T>
483           * Free an allocated element by putting it back to the freelist.           * Free an allocated element by putting it back to the freelist.
484           */           */
485          inline void free(T* element) {          inline void free(T* element) {
486              RTEList<T>::Node<T>* prevelem;              RTELNode<T>* prevelem;
487              RTEList<T>::Node<T>* nextelem;              RTELNode<T>* nextelem;
488              RTEList<T>::Node<T>* node;              RTELNode<T>* node;
489    
490              char* node_to_free = (char*) element;              char* node_to_free = (char*) element;
491              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)              // calculate the offset of the RTEListNode (see free_offset calculation in the constructor)
492              node_to_free -= free_offset;              node_to_free -= this->free_offset;
493              // insert the node to the beginning of the freelist              // insert the node to the beginning of the freelist
494              node = (RTEList<T>::Node<T>*) node_to_free;              node = (RTELNode<T>*) node_to_free;
495              prepend(node);              prepend(node);
496    
497              // now remove the element from the alloclist              // now remove the element from the alloclist
# Line 510  class RTELMemoryPool : public RTEList<T> Line 511  class RTELMemoryPool : public RTEList<T>
511           * @returns number of freed elements           * @returns number of freed elements
512           */           */
513          inline int clear() {          inline int clear() {
514              RTEList<T>::Node<T>* nextnode;              RTELNode<T>* nextnode;
515              RTEList<T>::Node<T>* prevelem;              RTELNode<T>* prevelem;
516              RTEList<T>::Node<T>* nextelem;              RTELNode<T>* nextelem;
517    
518              int count = 0;              int count = 0;
519    
520              acurrentnode = firstnode.anext;              this->acurrentnode = this->firstnode.anext;
521              if (acurrentnode->anext == acurrentnode) return 0;              if (this->acurrentnode->anext == this->acurrentnode) return 0;
522    
523              while (true) {              while (true) {
524                  nextnode = acurrentnode->anext;                  nextnode = this->acurrentnode->anext;
525    
526                  // prepend (insert at the beginning) the node to the freelist                  // prepend (insert at the beginning) the node to the freelist
527                  //printf("empty: putting back elem (node) %d to freelist\n",acurrentnode);                  //printf("empty: putting back elem (node) %d to freelist\n",acurrentnode);
528                  prepend(acurrentnode); count++;                  prepend(this->acurrentnode); count++;
529    
530                  // now remove the element from the alloclist                  // now remove the element from the alloclist
531                  prevelem        = acurrentnode->aprev;                  prevelem        = this->acurrentnode->aprev;
532                  nextelem        = acurrentnode->anext;                  nextelem        = this->acurrentnode->anext;
533                  prevelem->anext = nextelem;                  prevelem->anext = nextelem;
534                  nextelem->aprev = prevelem;                  nextelem->aprev = prevelem;
535    
536                  if (nextnode->anext == nextnode) return count;                  if (nextnode->anext == nextnode) return count;
537                  acurrentnode = nextnode;                  this->acurrentnode = nextnode;
538              }              }
539          }          }
540  };  };

Legend:
Removed from v.267  
changed lines
  Added in v.268

  ViewVC Help
Powered by ViewVC