Updated license from GPL version 2 or later to GPL version 3 or later.
[debian/gnuradio] / pmt / src / lib / pmt_pool.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2007 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <pmt_pool.h>
26 #include <algorithm>
27 #include <stdint.h>
28
29 static inline size_t
30 ROUNDUP(size_t x, size_t stride)
31 {
32   return ((((x) + (stride) - 1)/(stride)) * (stride));
33 }
34
35 pmt_pool::pmt_pool(size_t itemsize, size_t alignment, size_t allocation_size)
36   : d_itemsize(ROUNDUP(itemsize, alignment)),
37     d_alignment(alignment),
38     d_allocation_size(std::max(allocation_size, 16 * itemsize)),
39     d_freelist(0)
40 {
41 }
42
43 pmt_pool::~pmt_pool()
44 {
45   for (unsigned int i = 0; i < d_allocations.size(); i++){
46     delete [] d_allocations[i];
47   }
48 }
49
50 void *
51 pmt_pool::malloc()
52 {
53   omni_mutex_lock l(d_mutex);
54   item *p;
55
56   if (d_freelist){      // got something?
57     p = d_freelist;
58     d_freelist = p->d_next;
59     return p;
60   }
61
62   // allocate a new chunk
63   char *alloc = new char[d_allocation_size + d_alignment - 1];
64   d_allocations.push_back(alloc);
65
66   // get the alignment we require
67   char *start = (char *)(((uintptr_t)alloc + d_alignment-1) & -d_alignment);
68   char *end = alloc + d_allocation_size + d_alignment - 1;
69   size_t n = (end - start) / d_itemsize;
70
71   // link the new items onto the free list.
72   p = (item *) start;
73   for (size_t i = 0; i < n; i++){
74     p->d_next = d_freelist;
75     d_freelist = p;
76     p = (item *)((char *) p + d_itemsize);
77   }
78
79   // now return the first one
80   p = d_freelist;
81   d_freelist = p->d_next;
82   return p;
83 }
84
85 void
86 pmt_pool::free(void *foo)
87 {
88   if (!foo)
89     return;
90
91   omni_mutex_lock l(d_mutex);
92
93   item *p = (item *) foo;
94   p->d_next = d_freelist;
95   d_freelist = p;
96 }