Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
c05e897a
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c05e897a
编写于
2月 07, 2017
作者:
A
asaha
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
4a6f8a04
d651e805
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
243 addition
and
40 deletion
+243
-40
.hgtags
.hgtags
+2
-0
src/os/linux/vm/globals_linux.hpp
src/os/linux/vm/globals_linux.hpp
+5
-2
src/os/linux/vm/os_linux.cpp
src/os/linux/vm/os_linux.cpp
+66
-23
src/share/vm/gc_implementation/g1/concurrentMark.cpp
src/share/vm/gc_implementation/g1/concurrentMark.cpp
+3
-4
src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
+2
-2
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+31
-2
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+5
-1
src/share/vm/runtime/os.cpp
src/share/vm/runtime/os.cpp
+13
-2
src/share/vm/runtime/os.hpp
src/share/vm/runtime/os.hpp
+11
-2
src/share/vm/runtime/vm_version.cpp
src/share/vm/runtime/vm_version.cpp
+2
-2
test/runtime/os/AvailableProcessors.java
test/runtime/os/AvailableProcessors.java
+103
-0
未找到文件。
.hgtags
浏览文件 @
c05e897a
...
...
@@ -950,4 +950,6 @@ c0a1ba0df20fda10ddb8599e888eb56ad98b3874 jdk8u131-b00
ef90c721a4e59b01ca36f25619010a1afe9ed4d5 jdk8u131-b02
0ca47d0811b01ecf8651b6045a1e33a4a9bed0ee jdk8u131-b03
dab1d597165207e14b6886b1823c1e990bc776a3 jdk8u131-b04
c965fc1aa840a0903709ad69aa0e2100330ccd84 jdk8u131-b05
6e4cfbc7534f83902692132efb61683528c04a59 jdk8u131-b06
692bc6b674dcab72453de08ee9da0856a7e41c0f jdk8u141-b00
src/os/linux/vm/globals_linux.hpp
浏览文件 @
c05e897a
/*
* Copyright (c) 2005, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -47,7 +47,10 @@
"Load DLLs with executable-stack attribute in the VM Thread") \
\
product(bool, UseSHM, false, \
"Use SYSV shared memory for large pages")
"Use SYSV shared memory for large pages") \
\
diagnostic(bool, PrintActiveCpus, false, \
"Print the number of CPUs detected in os::active_processor_count")
//
// Defines Linux-specific default values. The flags are available on all
...
...
src/os/linux/vm/os_linux.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 1999, 201
5
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -104,6 +104,14 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <sched.h>
#undef _GNU_SOURCE
#else
#include <sched.h>
#endif
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
// getrusage() is prepared to handle the associated failure.
#ifndef RUSAGE_THREAD
...
...
@@ -1067,29 +1075,30 @@ static bool find_vma(address addr, address* vma_low, address* vma_high) {
// Locate initial thread stack. This special handling of initial thread stack
// is needed because pthread_getattr_np() on most (all?) Linux distros returns
// bogus value for initial thread.
// bogus value for the primordial process thread. While the launcher has created
// the VM in a new thread since JDK 6, we still have to allow for the use of the
// JNI invocation API from a primordial thread.
void
os
::
Linux
::
capture_initial_stack
(
size_t
max_size
)
{
// stack size is the easy part, get it from RLIMIT_STACK
size_t
stack_size
;
// max_size is either 0 (which means accept OS default for thread stacks) or
// a user-specified value known to be at least the minimum needed. If we
// are actually on the primordial thread we can make it appear that we have a
// smaller max_size stack by inserting the guard pages at that location. But we
// cannot do anything to emulate a larger stack than what has been provided by
// the OS or threading library. In fact if we try to use a stack greater than
// what is set by rlimit then we will crash the hosting process.
// Maximum stack size is the easy part, get it from RLIMIT_STACK.
// If this is "unlimited" then it will be a huge value.
struct
rlimit
rlim
;
getrlimit
(
RLIMIT_STACK
,
&
rlim
);
stack_size
=
rlim
.
rlim_cur
;
s
ize_t
s
tack_size
=
rlim
.
rlim_cur
;
// 6308388: a bug in ld.so will relocate its own .data section to the
// lower end of primordial stack; reduce ulimit -s value a little bit
// so we won't install guard page on ld.so's data section.
stack_size
-=
2
*
page_size
();
// 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
// 7.1, in both cases we will get 2G in return value.
// 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
// SuSE 7.2, Debian) can not handle alternate signal stack correctly
// for initial thread if its stack size exceeds 6M. Cap it at 2M,
// in case other parts in glibc still assumes 2M max stack size.
// FIXME: alt signal stack is gone, maybe we can relax this constraint?
// Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
if
(
stack_size
>
2
*
K
*
K
IA64_ONLY
(
*
2
))
stack_size
=
2
*
K
*
K
IA64_ONLY
(
*
2
);
// Try to figure out where the stack base (top) is. This is harder.
//
// When an application is started, glibc saves the initial stack pointer in
...
...
@@ -1249,14 +1258,18 @@ void os::Linux::capture_initial_stack(size_t max_size) {
// stack_top could be partially down the page so align it
stack_top
=
align_size_up
(
stack_top
,
page_size
());
if
(
max_size
&&
stack_size
>
max_size
)
{
_initial_thread_stack_size
=
max_size
;
// Allowed stack value is minimum of max_size and what we derived from rlimit
if
(
max_size
>
0
)
{
_initial_thread_stack_size
=
MIN2
(
max_size
,
stack_size
);
}
else
{
_initial_thread_stack_size
=
stack_size
;
// Accept the rlimit max, but if stack is unlimited then it will be huge, so
// clamp it at 8MB as we do on Solaris
_initial_thread_stack_size
=
MIN2
(
stack_size
,
8
*
M
);
}
_initial_thread_stack_size
=
align_size_down
(
_initial_thread_stack_size
,
page_size
());
_initial_thread_stack_bottom
=
(
address
)
stack_top
-
_initial_thread_stack_size
;
assert
(
_initial_thread_stack_bottom
<
(
address
)
stack_top
,
"overflow!"
);
}
////////////////////////////////////////////////////////////////////////////////
...
...
@@ -5016,12 +5029,42 @@ void os::make_polling_page_readable(void) {
}
};
static
int
os_cpu_count
(
const
cpu_set_t
*
cpus
)
{
int
count
=
0
;
// only look up to the number of configured processors
for
(
int
i
=
0
;
i
<
os
::
processor_count
();
i
++
)
{
if
(
CPU_ISSET
(
i
,
cpus
))
{
count
++
;
}
}
return
count
;
}
// Get the current number of available processors for this process.
// This value can change at any time during a process's lifetime.
// sched_getaffinity gives an accurate answer as it accounts for cpusets.
// If anything goes wrong we fallback to returning the number of online
// processors - which can be greater than the number available to the process.
int
os
::
active_processor_count
()
{
// Linux doesn't yet have a (official) notion of processor sets,
// so just return the number of online processors.
int
online_cpus
=
::
sysconf
(
_SC_NPROCESSORS_ONLN
);
assert
(
online_cpus
>
0
&&
online_cpus
<=
processor_count
(),
"sanity check"
);
return
online_cpus
;
cpu_set_t
cpus
;
// can represent at most 1024 (CPU_SETSIZE) processors
int
cpus_size
=
sizeof
(
cpu_set_t
);
int
cpu_count
=
0
;
// pid 0 means the current thread - which we have to assume represents the process
if
(
sched_getaffinity
(
0
,
cpus_size
,
&
cpus
)
==
0
)
{
cpu_count
=
os_cpu_count
(
&
cpus
);
if
(
PrintActiveCpus
)
{
tty
->
print_cr
(
"active_processor_count: sched_getaffinity processor count: %d"
,
cpu_count
);
}
}
else
{
cpu_count
=
::
sysconf
(
_SC_NPROCESSORS_ONLN
);
warning
(
"sched_getaffinity failed (%s)- using online processor count (%d) "
"which may exceed available processors"
,
strerror
(
errno
),
cpu_count
);
}
assert
(
cpu_count
>
0
&&
cpu_count
<=
processor_count
(),
"sanity check"
);
return
cpu_count
;
}
void
os
::
set_native_thread_name
(
const
char
*
name
)
{
...
...
src/share/vm/gc_implementation/g1/concurrentMark.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -631,11 +631,10 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev
double
overall_cm_overhead
=
(
double
)
MaxGCPauseMillis
*
marking_overhead
/
(
double
)
GCPauseIntervalMillis
;
double
cpu_ratio
=
1.0
/
(
double
)
os
::
processor_count
();
double
cpu_ratio
=
1.0
/
os
::
initial_active_
processor_count
();
double
marking_thread_num
=
ceil
(
overall_cm_overhead
/
cpu_ratio
);
double
marking_task_overhead
=
overall_cm_overhead
/
marking_thread_num
*
(
double
)
os
::
processor_count
();
overall_cm_overhead
/
marking_thread_num
*
os
::
initial_active_processor_count
();
double
sleep_factor
=
(
1.0
-
marking_task_overhead
)
/
marking_task_overhead
;
...
...
src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 2001, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -80,7 +80,7 @@ DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
// Determines how many mutator threads can process the buffers in parallel.
uint
DirtyCardQueueSet
::
num_par_ids
()
{
return
(
uint
)
os
::
processor_count
();
return
(
uint
)
os
::
initial_active_
processor_count
();
}
void
DirtyCardQueueSet
::
initialize
(
CardTableEntryClosure
*
cl
,
Monitor
*
cbl_mon
,
Mutex
*
fl_lock
,
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -1768,10 +1768,39 @@ void Arguments::set_heap_size() {
FLAG_SET_CMDLINE
(
uintx
,
MaxRAMFraction
,
DefaultMaxRAMFraction
);
}
const
julong
phys_mem
=
julong
phys_mem
=
FLAG_IS_DEFAULT
(
MaxRAM
)
?
MIN2
(
os
::
physical_memory
(),
(
julong
)
MaxRAM
)
:
(
julong
)
MaxRAM
;
// Experimental support for CGroup memory limits
if
(
UseCGroupMemoryLimitForHeap
)
{
// This is a rough indicator that a CGroup limit may be in force
// for this process
const
char
*
lim_file
=
"/sys/fs/cgroup/memory/memory.limit_in_bytes"
;
FILE
*
fp
=
fopen
(
lim_file
,
"r"
);
if
(
fp
!=
NULL
)
{
julong
cgroup_max
=
0
;
int
ret
=
fscanf
(
fp
,
JULONG_FORMAT
,
&
cgroup_max
);
if
(
ret
==
1
&&
cgroup_max
>
0
)
{
// If unlimited, cgroup_max will be a very large, but unspecified
// value, so use initial phys_mem as a limit
if
(
PrintGCDetails
&&
Verbose
)
{
// Cannot use gclog_or_tty yet.
tty
->
print_cr
(
"Setting phys_mem to the min of cgroup limit ("
JULONG_FORMAT
"MB) and initial phys_mem ("
JULONG_FORMAT
"MB)"
,
cgroup_max
/
M
,
phys_mem
/
M
);
}
phys_mem
=
MIN2
(
cgroup_max
,
phys_mem
);
}
else
{
warning
(
"Unable to read/parse cgroup memory limit from %s: %s"
,
lim_file
,
errno
!=
0
?
strerror
(
errno
)
:
"unknown error"
);
}
fclose
(
fp
);
}
else
{
warning
(
"Unable to open cgroup memory limit file %s (%s)"
,
lim_file
,
strerror
(
errno
));
}
}
// If the maximum heap size has not been set with -Xmx,
// then set it as fraction of the size of physical memory,
// respecting the maximum and minimum sizes of the heap.
...
...
src/share/vm/runtime/globals.hpp
浏览文件 @
c05e897a
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -2068,6 +2068,10 @@ class CommandLineFlags {
"Maximum ergonomically set heap size (in bytes); zero means use " \
"MaxRAM / MaxRAMFraction") \
\
experimental(bool, UseCGroupMemoryLimitForHeap, false, \
"Use CGroup memory limit as physical memory limit for heap " \
"sizing") \
\
product(uintx, MaxRAMFraction, 4, \
"Maximum fraction (1/n) of real memory used for maximum heap " \
"size") \
...
...
src/share/vm/runtime/os.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -78,6 +78,7 @@ volatile int32_t* os::_mem_serialize_page = NULL;
uintptr_t
os
::
_serialize_page_mask
=
0
;
long
os
::
_rand_seed
=
1
;
int
os
::
_processor_count
=
0
;
int
os
::
_initial_active_processor_count
=
0
;
size_t
os
::
_page_sizes
[
os
::
page_sizes_max
];
#ifndef PRODUCT
...
...
@@ -322,6 +323,7 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) {
}
void
os
::
init_before_ergo
()
{
initialize_initial_active_processor_count
();
// We need to initialize large page support here because ergonomics takes some
// decisions depending on large page support and the calculated large page size.
large_page_init
();
...
...
@@ -835,7 +837,11 @@ void os::print_cpu_info(outputStream* st) {
st
->
print
(
"CPU:"
);
st
->
print
(
"total %d"
,
os
::
processor_count
());
// It's not safe to query number of active processors after crash
// st->print("(active %d)", os::active_processor_count());
// st->print("(active %d)", os::active_processor_count()); but we can
// print the initial number of active processors.
// We access the raw value here because the assert in the accessor will
// fail if the crash occurs before initialization of this value.
st
->
print
(
" (initial active %d)"
,
_initial_active_processor_count
);
st
->
print
(
" %s"
,
VM_Version
::
cpu_features
());
st
->
cr
();
pd_print_cpu_info
(
st
);
...
...
@@ -1418,6 +1424,11 @@ bool os::is_server_class_machine() {
return
result
;
}
void
os
::
initialize_initial_active_processor_count
()
{
assert
(
_initial_active_processor_count
==
0
,
"Initial active processor count already set."
);
_initial_active_processor_count
=
active_processor_count
();
}
void
os
::
SuspendedThreadTask
::
run
()
{
assert
(
Threads_lock
->
owned_by_self
()
||
(
_thread
==
VMThread
::
vm_thread
()),
"must have threads lock to call this"
);
internal_do_task
();
...
...
src/share/vm/runtime/os.hpp
浏览文件 @
c05e897a
...
...
@@ -151,6 +151,7 @@ class os: AllStatic {
static
size_t
page_size_for_region
(
size_t
region_size
,
size_t
min_pages
,
bool
must_be_aligned
);
static
void
initialize_initial_active_processor_count
();
public:
static
void
init
(
void
);
// Called before command line parsing
static
void
init_before_ergo
(
void
);
// Called after command line parsing
...
...
@@ -238,6 +239,13 @@ class os: AllStatic {
// Note that on some OSes this can change dynamically.
static
int
active_processor_count
();
// At startup the number of active CPUs this process is allowed to run on.
// This value does not change dynamically. May be different from active_processor_count().
static
int
initial_active_processor_count
()
{
assert
(
_initial_active_processor_count
>
0
,
"Initial active processor count not set yet."
);
return
_initial_active_processor_count
;
}
// Bind processes to processors.
// This is a two step procedure:
// first you generate a distribution of processes to processors,
...
...
@@ -975,8 +983,9 @@ class os: AllStatic {
protected:
static
long
_rand_seed
;
// seed for random number generator
static
int
_processor_count
;
// number of processors
static
long
_rand_seed
;
// seed for random number generator
static
int
_processor_count
;
// number of processors
static
int
_initial_active_processor_count
;
// number of active processors during initialization.
static
char
*
format_boot_path
(
const
char
*
format_string
,
const
char
*
home
,
...
...
src/share/vm/runtime/vm_version.cpp
浏览文件 @
c05e897a
/*
* Copyright (c) 1998, 201
5
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -296,7 +296,7 @@ unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
// processor after the first 8. For example, on a 72 cpu machine
// and a chosen fraction of 5/8
// use 8 + (72 - 8) * (5/8) == 48 worker threads.
unsigned
int
ncpus
=
(
unsigned
int
)
os
::
active_processor_count
();
unsigned
int
ncpus
=
(
unsigned
int
)
os
::
initial_
active_processor_count
();
return
(
ncpus
<=
switch_pt
)
?
ncpus
:
(
switch_pt
+
((
ncpus
-
switch_pt
)
*
num
)
/
den
);
...
...
test/runtime/os/AvailableProcessors.java
0 → 100644
浏览文件 @
c05e897a
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.File
;
import
com.oracle.java.testlibrary.ProcessTools
;
import
com.oracle.java.testlibrary.OutputAnalyzer
;
import
java.util.ArrayList
;
/*
* @test
* @bug 6515172
* @summary Check that availableProcessors reports the correct value when running in a cpuset on linux
* @requires os.family == "linux"
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @run driver AvailableProcessors
*/
public
class
AvailableProcessors
{
static
final
String
SUCCESS_STRING
=
"Found expected processors: "
;
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
if
(
args
.
length
>
0
)
checkProcessors
(
Integer
.
parseInt
(
args
[
0
]));
else
{
// run ourselves under different cpu configurations
// using the taskset command
String
taskset
;
final
String
taskset1
=
"/bin/taskset"
;
final
String
taskset2
=
"/usr/bin/taskset"
;
if
(
new
File
(
taskset1
).
exists
())
taskset
=
taskset1
;
else
if
(
new
File
(
taskset2
).
exists
())
taskset
=
taskset2
;
else
{
System
.
out
.
println
(
"Skipping test: could not find taskset command"
);
return
;
}
int
available
=
Runtime
.
getRuntime
().
availableProcessors
();
if
(
available
==
1
)
{
System
.
out
.
println
(
"Skipping test: only one processor available"
);
return
;
}
// Get the java command we want to execute
// Enable logging for easier failure diagnosis
ProcessBuilder
master
=
ProcessTools
.
createJavaProcessBuilder
(
false
,
"-XX:+UnlockDiagnosticVMOptions"
,
"-XX:+PrintActiveCpus"
,
"AvailableProcessors"
);
int
[]
expected
=
new
int
[]
{
1
,
available
/
2
,
available
-
1
,
available
};
for
(
int
i
:
expected
)
{
System
.
out
.
println
(
"Testing for "
+
i
+
" processors ..."
);
int
max
=
i
-
1
;
ArrayList
<
String
>
cmdline
=
new
ArrayList
<>(
master
.
command
());
// prepend taskset command
cmdline
.
add
(
0
,
"0-"
+
max
);
cmdline
.
add
(
0
,
"-c"
);
cmdline
.
add
(
0
,
taskset
);
// append expected processor count
cmdline
.
add
(
String
.
valueOf
(
i
));
ProcessBuilder
pb
=
new
ProcessBuilder
(
cmdline
);
System
.
out
.
println
(
"Final command line: "
+
ProcessTools
.
getCommandLine
(
pb
));
OutputAnalyzer
output
=
ProcessTools
.
executeProcess
(
pb
);
output
.
shouldContain
(
SUCCESS_STRING
);
}
}
}
static
void
checkProcessors
(
int
expected
)
{
int
available
=
Runtime
.
getRuntime
().
availableProcessors
();
if
(
available
!=
expected
)
throw
new
Error
(
"Expected "
+
expected
+
" processors, but found "
+
available
);
else
System
.
out
.
println
(
SUCCESS_STRING
+
available
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录