Mercurial > hg > octave-nkf
annotate liboctave/oct-locbuf.cc @ 11542:695141f1c05c ss-3-3-55
snapshot 3.3.55
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 15 Jan 2011 04:53:04 -0500 |
parents | fd0a3ac60b0e |
children | 12df7854fa7c |
rev | line source |
---|---|
8400
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
1 /* |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
2 |
11523 | 3 Copyright (C) 2008-2011 Jaroslav Hajek |
8400
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
4 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
5 This file is part of Octave. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
6 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
7 Octave is free software; you can redistribute it and/or modify it |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
8 under the terms of the GNU General Public License as published by the |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
9 Free Software Foundation; either version 3 of the License, or (at your |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
10 option) any later version. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
11 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
12 Octave is distributed in the hope that it will be useful, but WITHOUT |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
15 for more details. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
16 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
17 You should have received a copy of the GNU General Public License |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
18 along with Octave; see the file COPYING. If not, see |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
19 <http://www.gnu.org/licenses/>. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
20 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
21 */ |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
22 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
23 #ifdef HAVE_CONFIG_H |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
24 #include <config.h> |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
25 #endif |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
26 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
27 #include <iostream> |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
28 #include "oct-locbuf.h" |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
29 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
30 // Query for configured chunk size, and if not defined, set it to 32 MB. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
31 // FIXME: 32MB is hard-coded. Maybe we could use something better, like |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
32 // querying for available physical memory. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
33 #ifndef OCTAVE_LOCBUF_CHUNKSIZE_MB |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
34 #define OCTAVE_LOCBUF_CHUNKSIZE_MB 32 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
35 #endif |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
36 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
37 // Each chunk will be at least this big. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
38 const size_t octave_chunk_buffer::chunk_size = |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
39 static_cast<size_t> (OCTAVE_LOCBUF_CHUNKSIZE_MB) << 20; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
40 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
41 char *octave_chunk_buffer::top = 0, *octave_chunk_buffer::chunk = 0; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
42 size_t octave_chunk_buffer::left = 0; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
43 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
44 octave_chunk_buffer::octave_chunk_buffer (size_t size) : cnk (0), dat (0) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
45 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
46 // Alignment mask. The size of double or long int, whichever is greater. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
47 // All data will be aligned to this size. If it's not enough for a type, |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
48 // that type should not be declared as POD. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
49 static const size_t align_mask = (sizeof (long) < sizeof (double) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
50 ? sizeof (double) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
51 : sizeof (long)) - 1; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
52 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
53 if (! size) return; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
54 // Align size. Note that size_t is unsigned, so size-1 must correctly |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
55 // wrap around. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
56 size = ((size - 1) | align_mask) + 1; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
57 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
58 if (size > left) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
59 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
60 // Big buffers (> 1/8 chunk) will be allocated as stand-alone and |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
61 // won't disrupt the chain. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
62 if (size > chunk_size >> 3) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
63 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
64 // Use new [] to get std::bad_alloc if out of memory. Could as |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
65 // well be std::malloc and handle that ourselves. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
66 dat = new char [size]; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
67 return; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
68 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
69 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
70 dat = new char [chunk_size]; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
71 chunk = top = dat; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
72 left = chunk_size; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
73 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
74 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
75 // Now allocate memory from the chunk and update state. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
76 cnk = chunk; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
77 dat = top; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
78 left -= size; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
79 top += size; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
80 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
81 |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
82 octave_chunk_buffer::~octave_chunk_buffer (void) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
83 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
84 if (cnk == chunk) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
85 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
86 // Our chunk is still the active one. Just restore the state. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
87 left += top - dat; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
88 top = dat; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
89 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
90 else if (! cnk) |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
91 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
92 // We were a stand-alone buffer. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
93 delete [] dat; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
94 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
95 else |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
96 { |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
97 // Responsible for deletion. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
98 delete [] chunk; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
99 chunk = cnk; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
100 top = dat; |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
101 // FIXME: This will only work if chunk_size is constant. |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
102 left = chunk_size - (dat - cnk); |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
103 } |
7b6e1fc1cb90
implement obstack-like optimization of local buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
diff
changeset
|
104 } |