GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-locbuf.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2008-2013 Jaroslav Hajek
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <iostream>
28 
29 #include "lo-error.h"
30 #include "oct-locbuf.h"
31 
32 // FIXME: Maybe we should querying for available physical memory?
33 
34 #ifndef OCTAVE_LOCBUF_CHUNKSIZE_MB
35 #define OCTAVE_LOCBUF_CHUNKSIZE_MB 32
36 #endif
37 
38 // Each chunk will be at least this big.
39 
41  static_cast<size_t> (OCTAVE_LOCBUF_CHUNKSIZE_MB) << 20;
42 
43 char *octave_chunk_buffer::top = 0;
45 size_t octave_chunk_buffer::left = 0;
47 
49 {
50  // Alignment mask. The size of double or long int, whichever is
51  // greater. All data will be aligned to this size. If it's not
52  // enough for a type, that type should not be declared as POD.
53 
54  static const size_t align_mask = (sizeof (long) < sizeof (double)
55  ? sizeof (double)
56  : sizeof (long)) - 1;
57 
58  active++;
59 
60  if (! size)
61  return;
62 
63  // Align size. Note that size_t is unsigned, so size-1 must correctly
64  // wrap around.
65 
66  size = ((size - 1) | align_mask) + 1;
67 
68  if (size > left)
69  {
70  // Big buffers (> 1/8 chunk) will be allocated as stand-alone and
71  // won't disrupt the chain.
72 
73  if (size > chunk_size >> 3)
74  {
75  // Use new [] to get std::bad_alloc if out of memory.
76 
77  dat = new char [size];
78  return;
79  }
80 
81  dat = new char [chunk_size];
82  chunk = top = dat;
83  left = chunk_size;
84  }
85 
86  // Now allocate memory from the chunk and update state.
87 
88  cnk = chunk;
89  dat = top;
90  left -= size;
91  top += size;
92 }
93 
95 {
96  active--;
97 
98  if (cnk == chunk)
99  {
100  // Our chunk is still the active one. Just restore the state.
101 
102  left += top - dat;
103  top = dat;
104  }
105  else
106  {
107  if (cnk)
108  {
109  // Responsible for deletion.
110 
111  delete [] chunk;
112  chunk = cnk;
113  top = dat;
114 
115  // FIXME: the following calcuation of remaining data will
116  // only work if each chunk has the same chunk_size.
117 
118  left = chunk_size - (dat - cnk);
119  }
120  else
121  {
122  // We were a stand-alone buffer.
123 
124  delete [] dat;
125  }
126  }
127 }
128 
129 // Clear the final chunk of allocated memory.
130 
131 void
133 {
134  if (active == 0)
135  {
136  delete [] chunk;
137  chunk = 0;
138  top = 0;
139  left = 0;
140  }
141  else
142  {
143  (*current_liboctave_warning_handler)
144  ("octave_chunk_buffer::clear: %d active allocations remain!",
145  active);
146  }
147 }