50113
|
1 |
/*
|
|
2 |
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation.
|
|
8 |
*
|
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
13 |
* accompanied this code).
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License version
|
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 |
*
|
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
20 |
* or visit www.oracle.com if you need additional information or have any
|
|
21 |
* questions.
|
|
22 |
*
|
|
23 |
*/
|
|
24 |
|
|
25 |
#include "precompiled.hpp"
|
|
26 |
#include "jfr/recorder/service/jfrMemorySizer.hpp"
|
|
27 |
#include "logging/log.hpp"
|
|
28 |
#include "runtime/os.hpp"
|
|
29 |
|
|
30 |
const julong MAX_ADJUSTED_GLOBAL_BUFFER_SIZE = 1 * M;
|
|
31 |
const julong MIN_ADJUSTED_GLOBAL_BUFFER_SIZE_CUTOFF = 512 * K;
|
|
32 |
const julong MIN_GLOBAL_BUFFER_SIZE = 64 * K;
|
|
33 |
// implies at least 2 * MIN_GLOBAL_BUFFER SIZE
|
|
34 |
const julong MIN_BUFFER_COUNT = 2;
|
|
35 |
// MAX global buffer count open ended
|
|
36 |
const julong DEFAULT_BUFFER_COUNT = 20;
|
|
37 |
// MAX thread local buffer size == size of a single global buffer (runtime determined)
|
|
38 |
// DEFAULT thread local buffer size = 2 * os page size (runtime determined)
|
|
39 |
const julong MIN_THREAD_BUFFER_SIZE = 4 * K;
|
|
40 |
const julong MIN_MEMORY_SIZE = 1 * M;
|
|
41 |
const julong DEFAULT_MEMORY_SIZE = 10 * M;
|
|
42 |
|
|
43 |
//
|
|
44 |
// In pages:
|
|
45 |
//
|
|
46 |
// units = total_pages / per_unit_pages
|
|
47 |
//
|
|
48 |
static julong div_pages(julong& total_pages, julong& per_unit_pages) {
|
|
49 |
assert(total_pages > 0, "invariant");
|
|
50 |
assert(per_unit_pages > 0, "invariant");
|
|
51 |
assert(total_pages >= per_unit_pages, "invariant");
|
|
52 |
|
|
53 |
const julong units = total_pages / per_unit_pages;
|
|
54 |
const julong rem = total_pages % per_unit_pages;
|
|
55 |
|
|
56 |
assert(units > 0, "invariant");
|
|
57 |
|
|
58 |
if (rem > 0) {
|
|
59 |
total_pages -= rem % units;
|
|
60 |
per_unit_pages += rem / units;
|
|
61 |
}
|
|
62 |
|
|
63 |
assert(per_unit_pages > 0, "invariant");
|
|
64 |
assert(total_pages % units == 0, "invariant");
|
|
65 |
assert(units * per_unit_pages == total_pages, "invariant");
|
|
66 |
assert(units == total_pages / per_unit_pages, "invariant");
|
|
67 |
|
|
68 |
return units;
|
|
69 |
}
|
|
70 |
|
|
71 |
static void page_size_align_up(julong& value) {
|
|
72 |
static const julong alignment = os::vm_page_size() - 1;
|
|
73 |
value = (value + alignment) & ~alignment;
|
|
74 |
}
|
|
75 |
|
|
76 |
//
|
|
77 |
// In bytes:
|
|
78 |
// units = total_bytes / per_unit_bytes
|
|
79 |
//
|
|
80 |
static julong div_total_by_per_unit(julong& total_bytes, julong& per_unit_bytes) {
|
|
81 |
assert(total_bytes > 0, "invariant");
|
|
82 |
assert(per_unit_bytes > 0, "invariant");
|
|
83 |
assert(total_bytes >= per_unit_bytes, "invariant");
|
|
84 |
|
|
85 |
page_size_align_up(total_bytes);
|
|
86 |
assert(total_bytes % os::vm_page_size() == 0, "invariant");
|
|
87 |
julong total_pages = total_bytes / os::vm_page_size();
|
|
88 |
|
|
89 |
page_size_align_up(per_unit_bytes);
|
|
90 |
assert(per_unit_bytes % os::vm_page_size() == 0, "invariant");
|
|
91 |
julong per_unit_pages = per_unit_bytes / os::vm_page_size();
|
|
92 |
|
|
93 |
const julong units = div_pages(total_pages, per_unit_pages);
|
|
94 |
assert(units > 0, "invariant");
|
|
95 |
|
|
96 |
total_bytes = total_pages * os::vm_page_size();
|
|
97 |
per_unit_bytes = per_unit_pages * os::vm_page_size();
|
|
98 |
|
|
99 |
assert(per_unit_bytes > 0, "invariant");
|
|
100 |
assert(total_bytes / per_unit_bytes == units, "invariant");
|
|
101 |
|
|
102 |
return units;
|
|
103 |
}
|
|
104 |
|
|
105 |
//
|
|
106 |
// per_unit_bytes = total_bytes / units
|
|
107 |
//
|
|
108 |
static julong div_total_by_units(julong& total_bytes, julong& units) {
|
|
109 |
page_size_align_up(total_bytes);
|
|
110 |
assert(total_bytes % os::vm_page_size() == 0, "invariant");
|
|
111 |
julong total_pages = total_bytes / os::vm_page_size();
|
|
112 |
assert(units > 0, "invariant");
|
|
113 |
|
|
114 |
julong per_unit_pages = total_pages <= units ? 1 : total_pages / units;
|
|
115 |
units = div_pages(total_pages, per_unit_pages);
|
|
116 |
|
|
117 |
julong per_unit_bytes = per_unit_pages * os::vm_page_size();
|
|
118 |
assert(per_unit_bytes % os::vm_page_size() == 0, "invariant");
|
|
119 |
|
|
120 |
total_bytes = total_pages * os::vm_page_size();
|
|
121 |
assert(total_bytes % os::vm_page_size() == 0, "invariant");
|
|
122 |
|
|
123 |
assert(total_bytes % units == 0, "invariant");
|
|
124 |
assert(total_bytes / units == per_unit_bytes, "invariant");
|
|
125 |
assert(units * per_unit_bytes == total_bytes, "invariant");
|
|
126 |
|
|
127 |
return per_unit_bytes;
|
|
128 |
}
|
|
129 |
|
|
130 |
//
|
|
131 |
// total_bytes = per_unit_bytes * units;
|
|
132 |
//
|
|
133 |
static julong multiply(julong& per_unit_bytes, julong& units) {
|
|
134 |
page_size_align_up(per_unit_bytes);
|
|
135 |
assert(per_unit_bytes % os::vm_page_size() == 0, "invariant");
|
|
136 |
assert(units > 0, "invariant");
|
|
137 |
|
|
138 |
julong total_bytes = per_unit_bytes * units;
|
|
139 |
assert(total_bytes % os::vm_page_size() == 0, "invariant");
|
|
140 |
|
|
141 |
assert(total_bytes % units == 0, "invariant");
|
|
142 |
assert(total_bytes / units == per_unit_bytes, "invariant");
|
|
143 |
assert(units * per_unit_bytes == total_bytes, "invariant");
|
|
144 |
|
|
145 |
return total_bytes;
|
|
146 |
}
|
|
147 |
|
|
148 |
// Total_bytes is explicitly set.
|
|
149 |
//
|
|
150 |
// Deduce other parameters by delegating to a sizing policy
|
|
151 |
template <typename SizingPolicy>
|
|
152 |
static julong adjust(JfrMemoryOptions* options) {
|
|
153 |
page_size_align_up(options->memory_size);
|
|
154 |
assert(options->memory_size % os::vm_page_size() == 0, "invariant");
|
|
155 |
julong total_pages = options->memory_size / os::vm_page_size();
|
|
156 |
assert(options->buffer_count > 0, "invariant");
|
|
157 |
julong per_unit_pages = total_pages / options->buffer_count;
|
|
158 |
page_size_align_up(options->thread_buffer_size);
|
|
159 |
assert(options->thread_buffer_size % os::vm_page_size() == 0, "invariant");
|
|
160 |
julong thread_buffer_pages = options->thread_buffer_size / os::vm_page_size();
|
|
161 |
|
|
162 |
SizingPolicy::adjust(total_pages, per_unit_pages, options->buffer_count, thread_buffer_pages, options->thread_buffer_size_configured);
|
|
163 |
assert(options->buffer_count * per_unit_pages == total_pages, "invariant");
|
|
164 |
|
|
165 |
const julong per_unit_bytes = per_unit_pages * os::vm_page_size();
|
|
166 |
options->memory_size = total_pages * os::vm_page_size();
|
|
167 |
options->thread_buffer_size = thread_buffer_pages * os::vm_page_size();
|
|
168 |
|
|
169 |
assert(options->memory_size % options->buffer_count == 0, "invariant");
|
|
170 |
assert(options->memory_size / options->buffer_count == per_unit_bytes, "invariant");
|
|
171 |
assert(options->buffer_count * per_unit_bytes == options->memory_size, "invariant");
|
|
172 |
assert(per_unit_bytes >= options->thread_buffer_size, "invariant");
|
|
173 |
return per_unit_bytes;
|
|
174 |
}
|
|
175 |
|
|
176 |
static void align_buffer_size(julong& buffer_size_in_pages, julong max_size_pages, julong min_size_pages, bool sizeup = false) {
|
|
177 |
buffer_size_in_pages = MIN2(buffer_size_in_pages, max_size_pages);
|
|
178 |
buffer_size_in_pages = MAX2(buffer_size_in_pages, min_size_pages);
|
|
179 |
size_t multiples = 0;
|
|
180 |
if (buffer_size_in_pages < max_size_pages) {
|
|
181 |
while (buffer_size_in_pages >=
|
|
182 |
(min_size_pages << (multiples + (sizeup ? 0 : 1)))) {
|
|
183 |
++multiples;
|
|
184 |
}
|
|
185 |
buffer_size_in_pages = min_size_pages << multiples;
|
|
186 |
}
|
|
187 |
assert(buffer_size_in_pages >= min_size_pages && buffer_size_in_pages <= max_size_pages, "invariant");
|
|
188 |
}
|
|
189 |
|
|
190 |
static void adjust_buffer_size_to_total_memory_size(julong& total_pages, julong& buffer_size_pages) {
|
|
191 |
static const julong max_buffer_size_pages = MAX_ADJUSTED_GLOBAL_BUFFER_SIZE / os::vm_page_size();
|
|
192 |
// If memory size is less than DEFAULT_MEMORY_SIZE,
|
|
193 |
// the adjustment algorithm can decrease the size of the global buffer
|
|
194 |
// all the way down to the MIN_GLOBAL_BUFFER_SIZE (taking embedded use case in account).
|
|
195 |
// If memory size is larger than DEFAULT_MEMORY_SIZE, the lowest size of
|
|
196 |
// a global buffer will be the size of MIN_ADJUSTED_GLOBAL_BUFFER_SIZE_CUTOFF
|
|
197 |
static const julong min_buffer_size_pages =
|
|
198 |
total_pages * os::vm_page_size() < DEFAULT_MEMORY_SIZE ?
|
|
199 |
MIN_GLOBAL_BUFFER_SIZE / os::vm_page_size() :
|
|
200 |
MIN_ADJUSTED_GLOBAL_BUFFER_SIZE_CUTOFF / os::vm_page_size();
|
|
201 |
|
|
202 |
align_buffer_size(buffer_size_pages, max_buffer_size_pages, min_buffer_size_pages);
|
|
203 |
assert(buffer_size_pages % min_buffer_size_pages == 0, "invariant");
|
|
204 |
|
|
205 |
julong remainder = total_pages % buffer_size_pages;
|
|
206 |
while (remainder >= (buffer_size_pages >> 1)) {
|
|
207 |
if (buffer_size_pages <= min_buffer_size_pages) {
|
|
208 |
break;
|
|
209 |
}
|
|
210 |
buffer_size_pages >>= 1;
|
|
211 |
remainder = total_pages % buffer_size_pages;
|
|
212 |
}
|
|
213 |
}
|
|
214 |
|
|
215 |
// Sizing policy class
|
|
216 |
class ScaleOutAdjuster : public AllStatic {
|
|
217 |
public:
|
|
218 |
static void adjust(julong& total_pages,
|
|
219 |
julong& buffer_size_pages,
|
|
220 |
julong& buffer_count,
|
|
221 |
julong& thread_buffer_size_pages,
|
|
222 |
bool is_thread_buffer_size_set) {
|
|
223 |
assert(buffer_count > 0, "invariant");
|
|
224 |
adjust_buffer_size_to_total_memory_size(total_pages, buffer_size_pages);
|
|
225 |
assert(buffer_size_pages * os::vm_page_size() >= MIN_GLOBAL_BUFFER_SIZE, "invariant");
|
|
226 |
assert((buffer_size_pages * os::vm_page_size()) % MIN_GLOBAL_BUFFER_SIZE == 0, "invariant");
|
|
227 |
if (is_thread_buffer_size_set) {
|
|
228 |
if (thread_buffer_size_pages > buffer_size_pages) {
|
|
229 |
buffer_size_pages = thread_buffer_size_pages;
|
|
230 |
}
|
|
231 |
}
|
|
232 |
// and with this information, calculate what the new buffer count will be
|
|
233 |
buffer_count = div_pages(total_pages, buffer_size_pages);
|
|
234 |
}
|
|
235 |
};
|
|
236 |
|
|
237 |
static void memory_and_thread_buffer_size(JfrMemoryOptions* options) {
|
|
238 |
assert(options->memory_size_configured, "invariant");
|
|
239 |
assert(!options->buffer_count_configured, "invariant");
|
|
240 |
assert(!options->global_buffer_size_configured, "invariant");
|
|
241 |
// here the only thing specified is the overall total memory size
|
|
242 |
// we can and will apply some sizing heuristics to derive both
|
|
243 |
// the size of an individual global buffer and by implication the number of global
|
|
244 |
// buffers to use. Starting values for buffer count and global_buffer_size
|
|
245 |
// will be the defaults.
|
|
246 |
options->global_buffer_size = adjust<ScaleOutAdjuster>(options);
|
|
247 |
}
|
|
248 |
|
|
249 |
static void memory_size_and_buffer_count(JfrMemoryOptions* options) {
|
|
250 |
assert(options->memory_size_configured, "invariant");
|
|
251 |
assert(!options->global_buffer_size_configured, "invariant");
|
|
252 |
assert(!options->thread_buffer_size_configured, "invariant");
|
|
253 |
assert(options->buffer_count_configured, "invariant");
|
|
254 |
options->global_buffer_size = div_total_by_units(options->memory_size, options->buffer_count);
|
|
255 |
}
|
|
256 |
|
|
257 |
static void memory_size_and_global_buffer_size(JfrMemoryOptions* options) {
|
|
258 |
assert(options->memory_size_configured, "invariant");
|
|
259 |
assert(options->global_buffer_size_configured, "invariant");
|
|
260 |
assert(!options->buffer_count_configured, "invariant");
|
|
261 |
page_size_align_up(options->thread_buffer_size);
|
|
262 |
options->buffer_count = div_total_by_per_unit(options->memory_size, options->global_buffer_size);
|
|
263 |
if (options->thread_buffer_size > options->global_buffer_size) {
|
|
264 |
options->global_buffer_size = options->thread_buffer_size;
|
|
265 |
options->buffer_count = div_total_by_per_unit(options->memory_size, options->global_buffer_size);
|
|
266 |
}
|
|
267 |
assert(options->global_buffer_size >= options->thread_buffer_size, "invariant");
|
|
268 |
}
|
|
269 |
|
|
270 |
static bool is_ambiguous(const JfrMemoryOptions* options) {
|
|
271 |
assert(options->memory_size_configured, "invariant");
|
|
272 |
assert(options->global_buffer_size_configured, "invariant");
|
|
273 |
assert(options->buffer_count_configured, "invariant");
|
|
274 |
assert(options->thread_buffer_size <= options->global_buffer_size, "invariant");
|
|
275 |
// This can cause an ambiguous situation because all three parameters are explicitly set.
|
|
276 |
return options->global_buffer_size * options->buffer_count != options->memory_size;
|
|
277 |
}
|
|
278 |
|
|
279 |
static void all_options_set(JfrMemoryOptions* options) {
|
|
280 |
options->buffer_count = div_total_by_per_unit(options->memory_size, options->global_buffer_size);
|
|
281 |
page_size_align_up(options->thread_buffer_size);
|
|
282 |
if (options->thread_buffer_size > options->global_buffer_size) {
|
|
283 |
options->global_buffer_size = options->thread_buffer_size;
|
|
284 |
options->buffer_count = div_total_by_per_unit(options->memory_size, options->global_buffer_size);
|
|
285 |
}
|
|
286 |
assert(options->global_buffer_size >= options->thread_buffer_size, "invariant");
|
|
287 |
assert(options->memory_size / options->global_buffer_size == options->buffer_count, "invariant");
|
|
288 |
assert(options->memory_size % options->global_buffer_size == 0, "invariant");
|
|
289 |
}
|
|
290 |
|
|
291 |
static void global_buffer_size(JfrMemoryOptions* options) {
|
|
292 |
assert(!options->memory_size_configured, "invariant");
|
|
293 |
page_size_align_up(options->thread_buffer_size);
|
|
294 |
if (options->thread_buffer_size > options->global_buffer_size) {
|
|
295 |
options->global_buffer_size = options->thread_buffer_size;
|
|
296 |
}
|
|
297 |
options->memory_size = multiply(options->global_buffer_size, options->buffer_count);
|
|
298 |
assert(options->global_buffer_size >= options->thread_buffer_size, "invariant");
|
|
299 |
}
|
|
300 |
|
|
301 |
static void thread_buffer_size(JfrMemoryOptions* options) {
|
|
302 |
assert(!options->global_buffer_size_configured, "invariant");
|
|
303 |
assert(options->thread_buffer_size_configured, "invariant");
|
|
304 |
page_size_align_up(options->thread_buffer_size);
|
|
305 |
options->global_buffer_size = div_total_by_units(options->memory_size, options->buffer_count);
|
|
306 |
if (options->thread_buffer_size > options->global_buffer_size) {
|
|
307 |
options->global_buffer_size = options->thread_buffer_size;
|
|
308 |
options->buffer_count = div_total_by_per_unit(options->memory_size, options->global_buffer_size);
|
|
309 |
}
|
|
310 |
assert(options->global_buffer_size >= options->thread_buffer_size, "invariant");
|
|
311 |
}
|
|
312 |
|
|
313 |
static void default_size(const JfrMemoryOptions* options) {
|
|
314 |
// no memory options explicitly set
|
|
315 |
// default values already statically adjusted
|
|
316 |
assert(!options->thread_buffer_size_configured, "invariant");
|
|
317 |
assert(!options->memory_size_configured, "invariant");
|
|
318 |
assert(!options->buffer_count_configured, "invarinat");
|
|
319 |
assert(!options->global_buffer_size_configured, "invariant");
|
|
320 |
}
|
|
321 |
|
|
322 |
#ifdef ASSERT
|
|
323 |
static void assert_post_condition(const JfrMemoryOptions* options) {
|
|
324 |
assert(options->memory_size % os::vm_page_size() == 0, "invariant");
|
|
325 |
assert(options->global_buffer_size % os::vm_page_size() == 0, "invariant");
|
|
326 |
assert(options->thread_buffer_size % os::vm_page_size() == 0, "invariant");
|
|
327 |
assert(options->buffer_count > 0, "invariant");
|
|
328 |
}
|
|
329 |
#endif
|
|
330 |
|
|
331 |
// MEMORY SIZING ALGORITHM
|
|
332 |
|
|
333 |
bool JfrMemorySizer::adjust_options(JfrMemoryOptions* options) {
|
|
334 |
assert(options != NULL, "invariant");
|
|
335 |
|
|
336 |
enum MemoryOptions {
|
|
337 |
MEMORY_SIZE = 1,
|
|
338 |
GLOBAL_BUFFER_SIZE = 2,
|
|
339 |
GLOBAL_BUFFER_COUNT = 4,
|
|
340 |
THREAD_BUFFER_SIZE = 8
|
|
341 |
};
|
|
342 |
|
|
343 |
// LEGEND
|
|
344 |
//
|
|
345 |
// M = "memorysize" option
|
|
346 |
// G = "globalbuffersize" option
|
|
347 |
// C = "numglobalbuffers" option
|
|
348 |
// T = "threadbuffersize" option
|
|
349 |
//
|
|
350 |
// The memory options comprise an n-set (a 4-set) = { M, G, C, T }
|
|
351 |
//
|
|
352 |
// Number of r-subsets = 5 (0, 1, 2, 3, 4) (including null set)
|
|
353 |
//
|
|
354 |
// Unordered selection:
|
|
355 |
//
|
|
356 |
// C(4, 0) = {} = NULL set = 1
|
|
357 |
// C(4, 1) = { (M), (G), (C), (T) } = 4
|
|
358 |
// C(4, 2) = { (M, G), (M, C), (M, T), (G, C), (G, T), (C, T) } = 6
|
|
359 |
// C(4, 3) = { (M, G, C), (M, G, T), (M, C, T), (G, C, T) } = 4
|
|
360 |
// C(4, 4) = { (M, G, C, T) } = 1
|
|
361 |
//
|
|
362 |
// in shorter terms: P({ M, G, C, T}) = 16
|
|
363 |
//
|
|
364 |
#define MG (MEMORY_SIZE | GLOBAL_BUFFER_SIZE)
|
|
365 |
#define MC (MEMORY_SIZE | GLOBAL_BUFFER_COUNT)
|
|
366 |
#define MT (MEMORY_SIZE | THREAD_BUFFER_SIZE)
|
|
367 |
#define MGC (MG | GLOBAL_BUFFER_COUNT)
|
|
368 |
#define MGT (MG | THREAD_BUFFER_SIZE)
|
|
369 |
#define MCT (MC | THREAD_BUFFER_SIZE)
|
|
370 |
#define MGCT (MGC | THREAD_BUFFER_SIZE)
|
|
371 |
#define GC (GLOBAL_BUFFER_SIZE | GLOBAL_BUFFER_COUNT)
|
|
372 |
#define GT (GLOBAL_BUFFER_SIZE | THREAD_BUFFER_SIZE)
|
|
373 |
#define GCT (GC | THREAD_BUFFER_SIZE)
|
|
374 |
#define CT (GLOBAL_BUFFER_COUNT | THREAD_BUFFER_SIZE)
|
|
375 |
|
|
376 |
int set_of_options = 0;
|
|
377 |
|
|
378 |
if (options->memory_size_configured) {
|
|
379 |
set_of_options |= MEMORY_SIZE;
|
|
380 |
}
|
|
381 |
if (options->global_buffer_size_configured) {
|
|
382 |
set_of_options |= GLOBAL_BUFFER_SIZE;
|
|
383 |
}
|
|
384 |
if (options->buffer_count_configured) {
|
|
385 |
set_of_options |= GLOBAL_BUFFER_COUNT;
|
|
386 |
}
|
|
387 |
if (options->thread_buffer_size_configured) {
|
|
388 |
set_of_options |= THREAD_BUFFER_SIZE;
|
|
389 |
}
|
|
390 |
|
|
391 |
switch (set_of_options) {
|
|
392 |
case MT:
|
|
393 |
case MEMORY_SIZE:
|
|
394 |
memory_and_thread_buffer_size(options);
|
|
395 |
break;
|
|
396 |
case MC:
|
|
397 |
memory_size_and_buffer_count(options);
|
|
398 |
break;
|
|
399 |
case MGT:
|
|
400 |
assert(options->thread_buffer_size_configured, "invariant");
|
|
401 |
case MG:
|
|
402 |
memory_size_and_global_buffer_size(options);
|
|
403 |
break;
|
|
404 |
case MGC:
|
|
405 |
case MGCT:
|
|
406 |
if (is_ambiguous(options)) {
|
|
407 |
// Let the user resolve the ambiguity by bailing.
|
|
408 |
return false;
|
|
409 |
}
|
|
410 |
all_options_set(options);
|
|
411 |
break;
|
|
412 |
case GCT:
|
|
413 |
assert(options->buffer_count_configured, "invariant");
|
|
414 |
assert(options->thread_buffer_size_configured, "invariant");
|
|
415 |
case GC:
|
|
416 |
assert(options->global_buffer_size_configured, "invariant");
|
|
417 |
case GT:
|
|
418 |
case GLOBAL_BUFFER_COUNT:
|
|
419 |
case GLOBAL_BUFFER_SIZE:
|
|
420 |
global_buffer_size(options);
|
|
421 |
break;
|
|
422 |
case MCT:
|
|
423 |
assert(options->memory_size_configured, "invariant");
|
|
424 |
case CT:
|
|
425 |
assert(options->buffer_count_configured, "invariant");
|
|
426 |
case THREAD_BUFFER_SIZE:
|
|
427 |
thread_buffer_size(options);
|
|
428 |
break;
|
|
429 |
default:
|
|
430 |
default_size(options);
|
|
431 |
}
|
|
432 |
DEBUG_ONLY(assert_post_condition(options);)
|
|
433 |
return true;
|
|
434 |
}
|