summaryrefslogtreecommitdiff
path: root/ACE/ace/Free_List.cpp
blob: b576432c56fb488ce72de0052991e91b756982a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef ACE_FREE_LIST_CPP
#define ACE_FREE_LIST_CPP

#include "ace/Free_List.h"
#include "ace/Guard_T.h"

#if defined (ACE_HAS_ALLOC_HOOKS)
# include "ace/Malloc_Base.h"
#endif /* ACE_HAS_ALLOC_HOOKS */

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

// Default constructor that takes in a preallocation number
// (<prealloc>), a low and high water mark (<lwm> and <hwm>) and an
// increment value (<inc>)

template <class T, class ACE_LOCK>
ACE_Locked_Free_List<T, ACE_LOCK>::ACE_Locked_Free_List (int mode,
                                                     size_t prealloc,
                                                     size_t lwm,
                                                     size_t hwm,
                                                     size_t inc)
  : mode_ (mode),
    free_list_ (0),
    lwm_ (lwm),
    hwm_ (hwm),
    inc_ (inc),
    size_ (0)
{
  this->alloc (prealloc);
}

// Destructor - removes all the elements from the free_list

template <class T, class ACE_LOCK>
ACE_Locked_Free_List<T, ACE_LOCK>::~ACE_Locked_Free_List ()
{
  if (this->mode_ != ACE_PURE_FREE_LIST)
    while (this->free_list_ != 0)
      {
        T *temp = this->free_list_;
        this->free_list_ = this->free_list_->get_next ();
        delete temp;
      }
}

// Inserts an element onto the free list (if we are allowed to manage
// elements withing and it pasts the high water mark, delete the
// element)

template <class T, class ACE_LOCK> void
ACE_Locked_Free_List<T, ACE_LOCK>::add (T *element)
{
  ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));

  // Check to see that we not at the high water mark.
  if (this->mode_ == ACE_PURE_FREE_LIST
      || this->size_ < this->hwm_)
    {
      element->set_next (this->free_list_);
      this->free_list_ = element;
      this->size_++;
    }
  else
    delete element;
}

// Takes a element off the freelist and returns it.  It creates <inc>
// new elements if we are allowed to do it and the size is at the low
// water mark.

template <class T, class ACE_LOCK> T *
ACE_Locked_Free_List<T, ACE_LOCK>::remove ()
{
  ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, 0));

  // If we are at the low water mark, add some nodes
  if (this->mode_ != ACE_PURE_FREE_LIST && this->size_ <= this->lwm_)
    this->alloc (this->inc_);

  // Remove a node
  T *temp = this->free_list_;

  if (temp != 0)
    {
      this->free_list_ = this->free_list_->get_next ();
      this->size_--;
    }

  return temp;
}


// Returns the current size of the free list

template <class T, class ACE_LOCK> size_t
ACE_Locked_Free_List<T, ACE_LOCK>::size ()
{
  return this->size_;
}

// Resizes the free list to <newsize>

template <class T, class ACE_LOCK> void
ACE_Locked_Free_List<T, ACE_LOCK>::resize (size_t newsize)
{
  ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));

  // Check if we are allowed to resize
  if (this->mode_ != ACE_PURE_FREE_LIST)
    {
      // Check to see if we grow or shrink
      if (newsize < this->size_)
        {
          this->dealloc (this->size_ - newsize);
        }
      else
        {
          this->alloc (newsize - this->size_);
        }
    }
}

// Allocates <n> extra nodes for the freelist

template <class T, class ACE_LOCK> void
ACE_Locked_Free_List<T, ACE_LOCK>::alloc (size_t n)
{
  for (; n > 0; n--)
    {
      T *temp = 0;
      ACE_NEW (temp, T);
      temp->set_next (this->free_list_);
      this->free_list_ = temp;
      this->size_++;
    }
}

// Removes and frees <n> nodes from the freelist.

template <class T, class ACE_LOCK> void
ACE_Locked_Free_List<T, ACE_LOCK>::dealloc (size_t n)
{
  for (; this->free_list_ != 0 && n > 0;
       n--)
    {
      T *temp = this->free_list_;
      this->free_list_ = this->free_list_->get_next ();
      delete temp;
      this->size_--;
    }
}

ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Locked_Free_List)

ACE_END_VERSIONED_NAMESPACE_DECL

#endif /* ACE_FREE_LIST_CPP */