Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
72ae63a4
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
72ae63a4
编写于
4月 11, 2014
作者:
P
pliden
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8039147: Cleanup SuspendibleThreadSet
Reviewed-by: brutisso, tschatzl, mgerdin
上级
49dad6d9
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
270 addition
and
304 deletion
+270
-304
hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
...hare/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
+28
-40
hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
...hare/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
+0
-5
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+11
-15
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+0
-1
hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
...rc/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
+15
-18
hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp
...rc/share/vm/gc_implementation/g1/concurrentMarkThread.hpp
+0
-3
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
...pot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+5
-8
hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp
...src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp
+27
-28
hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp
.../share/vm/gc_implementation/shared/concurrentGCThread.cpp
+0
-110
hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp
.../share/vm/gc_implementation/shared/concurrentGCThread.hpp
+1
-70
hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp
...hare/vm/gc_implementation/shared/suspendibleThreadSet.cpp
+93
-0
hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp
...hare/vm/gc_implementation/shared/suspendibleThreadSet.hpp
+84
-0
hotspot/src/share/vm/runtime/mutexLocker.cpp
hotspot/src/share/vm/runtime/mutexLocker.cpp
+2
-2
hotspot/src/share/vm/runtime/mutexLocker.hpp
hotspot/src/share/vm/runtime/mutexLocker.hpp
+1
-1
hotspot/src/share/vm/runtime/safepoint.cpp
hotspot/src/share/vm/runtime/safepoint.cpp
+3
-3
未找到文件。
hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
浏览文件 @
72ae63a4
...
...
@@ -71,6 +71,7 @@ void ConcurrentG1RefineThread::initialize() {
}
void
ConcurrentG1RefineThread
::
sample_young_list_rs_lengths
()
{
SuspendibleThreadSetJoiner
sts
;
G1CollectedHeap
*
g1h
=
G1CollectedHeap
::
heap
();
G1CollectorPolicy
*
g1p
=
g1h
->
g1_policy
();
if
(
g1p
->
adaptive_young_list_length
())
{
...
...
@@ -82,8 +83,8 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
// we try to yield every time we visit 10 regions
if
(
regions_visited
==
10
)
{
if
(
_
sts
.
should_yield
())
{
_sts
.
yield
(
"G1 refine"
);
if
(
sts
.
should_yield
())
{
sts
.
yield
(
);
// we just abandon the iteration
break
;
}
...
...
@@ -99,9 +100,7 @@ void ConcurrentG1RefineThread::run_young_rs_sampling() {
DirtyCardQueueSet
&
dcqs
=
JavaThread
::
dirty_card_queue_set
();
_vtime_start
=
os
::
elapsedVTime
();
while
(
!
_should_terminate
)
{
_sts
.
join
();
sample_young_list_rs_lengths
();
_sts
.
leave
();
if
(
os
::
supports_vtime
())
{
_vtime_accum
=
(
os
::
elapsedVTime
()
-
_vtime_start
);
...
...
@@ -182,37 +181,37 @@ void ConcurrentG1RefineThread::run() {
break
;
}
_sts
.
join
();
{
SuspendibleThreadSetJoiner
sts
;
do
{
int
curr_buffer_num
=
(
int
)
dcqs
.
completed_buffers_num
();
// If the number of the buffers falls down into the yellow zone,
// that means that the transition period after the evacuation pause has ended.
if
(
dcqs
.
completed_queue_padding
()
>
0
&&
curr_buffer_num
<=
cg1r
()
->
yellow_zone
())
{
dcqs
.
set_completed_queue_padding
(
0
);
}
do
{
int
curr_buffer_num
=
(
int
)
dcqs
.
completed_buffers_num
();
// If the number of the buffers falls down into the yellow zone,
// that means that the transition period after the evacuation pause has ended.
if
(
dcqs
.
completed_queue_padding
()
>
0
&&
curr_buffer_num
<=
cg1r
()
->
yellow_zone
())
{
dcqs
.
set_completed_queue_padding
(
0
);
}
if
(
_worker_id
>
0
&&
curr_buffer_num
<=
_deactivation_threshold
)
{
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
deactivate
();
break
;
}
if
(
_worker_id
>
0
&&
curr_buffer_num
<=
_deactivation_threshold
)
{
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
deactivate
();
break
;
}
// Check if we need to activate the next thread.
if
(
_next
!=
NULL
&&
!
_next
->
is_active
()
&&
curr_buffer_num
>
_next
->
_threshold
)
{
_next
->
activate
();
}
}
while
(
dcqs
.
apply_closure_to_completed_buffer
(
_worker_id
+
_worker_id_offset
,
cg1r
()
->
green_zone
()));
// Check if we need to activate the next thread.
if
(
_next
!=
NULL
&&
!
_next
->
is_active
()
&&
curr_buffer_num
>
_next
->
_threshold
)
{
_next
->
activate
();
}
}
while
(
dcqs
.
apply_closure_to_completed_buffer
(
_worker_id
+
_worker_id_offset
,
cg1r
()
->
green_zone
()));
// We can exit the loop above while being active if there was a yield request.
if
(
is_active
())
{
deactivate
();
// We can exit the loop above while being active if there was a yield request.
if
(
is_active
())
{
deactivate
();
}
}
_sts
.
leave
();
if
(
os
::
supports_vtime
())
{
_vtime_accum
=
(
os
::
elapsedVTime
()
-
_vtime_start
);
}
else
{
...
...
@@ -223,17 +222,6 @@ void ConcurrentG1RefineThread::run() {
terminate
();
}
void
ConcurrentG1RefineThread
::
yield
()
{
if
(
G1TraceConcRefinement
)
{
gclog_or_tty
->
print_cr
(
"G1-Refine-yield"
);
}
_sts
.
yield
(
"G1 refine"
);
if
(
G1TraceConcRefinement
)
{
gclog_or_tty
->
print_cr
(
"G1-Refine-yield-end"
);
}
}
void
ConcurrentG1RefineThread
::
stop
()
{
// it is ok to take late safepoints here, if needed
{
...
...
hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
浏览文件 @
72ae63a4
...
...
@@ -64,9 +64,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
void
activate
();
void
deactivate
();
// For use by G1CollectedHeap, which is a friend.
static
SuspendibleThreadSet
*
sts
()
{
return
&
_sts
;
}
public:
virtual
void
run
();
// Constructor
...
...
@@ -84,8 +81,6 @@ public:
ConcurrentG1Refine
*
cg1r
()
{
return
_cg1r
;
}
// Yield for GC
void
yield
();
// shutdown
void
stop
();
};
...
...
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
浏览文件 @
72ae63a4
...
...
@@ -976,11 +976,11 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
}
if
(
concurrent
())
{
ConcurrentGCThread
::
stsL
eave
();
SuspendibleThreadSet
::
l
eave
();
}
_first_overflow_barrier_sync
.
enter
();
if
(
concurrent
())
{
ConcurrentGCThread
::
stsJ
oin
();
SuspendibleThreadSet
::
j
oin
();
}
// at this point everyone should have synced up and not be doing any
// more work
...
...
@@ -1024,11 +1024,11 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
}
if
(
concurrent
())
{
ConcurrentGCThread
::
stsL
eave
();
SuspendibleThreadSet
::
l
eave
();
}
_second_overflow_barrier_sync
.
enter
();
if
(
concurrent
())
{
ConcurrentGCThread
::
stsJ
oin
();
SuspendibleThreadSet
::
j
oin
();
}
// at this point everything should be re-initialized and ready to go
...
...
@@ -1076,7 +1076,7 @@ public:
double
start_vtime
=
os
::
elapsedVTime
();
ConcurrentGCThread
::
stsJ
oin
();
SuspendibleThreadSet
::
j
oin
();
assert
(
worker_id
<
_cm
->
active_tasks
(),
"invariant"
);
CMTask
*
the_task
=
_cm
->
task
(
worker_id
);
...
...
@@ -1103,9 +1103,9 @@ public:
if
(
!
_cm
->
has_aborted
()
&&
the_task
->
has_aborted
())
{
sleep_time_ms
=
(
jlong
)
(
elapsed_vtime_sec
*
_cm
->
sleep_factor
()
*
1000.0
);
ConcurrentGCThread
::
stsL
eave
();
SuspendibleThreadSet
::
l
eave
();
os
::
sleep
(
Thread
::
current
(),
sleep_time_ms
,
false
);
ConcurrentGCThread
::
stsJ
oin
();
SuspendibleThreadSet
::
j
oin
();
}
double
end_time2_sec
=
os
::
elapsedTime
();
double
elapsed_time2_sec
=
end_time2_sec
-
start_time_sec
;
...
...
@@ -1123,7 +1123,7 @@ public:
the_task
->
record_end_time
();
guarantee
(
!
the_task
->
has_aborted
()
||
_cm
->
has_aborted
(),
"invariant"
);
ConcurrentGCThread
::
stsL
eave
();
SuspendibleThreadSet
::
l
eave
();
double
end_vtime
=
os
::
elapsedVTime
();
_cm
->
update_accum_task_vtime
(
worker_id
,
end_vtime
-
start_vtime
);
...
...
@@ -3302,21 +3302,17 @@ void ConcurrentMark::print_on_error(outputStream* st) const {
// We take a break if someone is trying to stop the world.
bool
ConcurrentMark
::
do_yield_check
(
uint
worker_id
)
{
if
(
should_yield
())
{
if
(
SuspendibleThreadSet
::
should_yield
())
{
if
(
worker_id
==
0
)
{
_g1h
->
g1_policy
()
->
record_concurrent_pause
();
}
cmThread
()
->
yield
();
SuspendibleThreadSet
::
yield
();
return
true
;
}
else
{
return
false
;
}
}
bool
ConcurrentMark
::
should_yield
()
{
return
cmThread
()
->
should_yield
();
}
bool
ConcurrentMark
::
containing_card_is_marked
(
void
*
p
)
{
size_t
offset
=
pointer_delta
(
p
,
_g1h
->
reserved_region
().
start
(),
1
);
return
_card_bm
.
at
(
offset
>>
CardTableModRefBS
::
card_shift
);
...
...
@@ -3605,7 +3601,7 @@ void CMTask::regular_clock_call() {
#endif // _MARKING_STATS_
// (4) We check whether we should yield. If we have to, then we abort.
if
(
_cm
->
should_yield
())
{
if
(
SuspendibleThreadSet
::
should_yield
())
{
// We should yield. To do this we abort the task. The caller is
// responsible for yielding.
set_has_aborted
();
...
...
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
浏览文件 @
72ae63a4
...
...
@@ -814,7 +814,6 @@ public:
}
inline
bool
do_yield_check
(
uint
worker_i
=
0
);
inline
bool
should_yield
();
// Called to abort the marking cycle after a Full GC takes place.
void
abort
();
...
...
hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
浏览文件 @
72ae63a4
...
...
@@ -194,9 +194,8 @@ void ConcurrentMarkThread::run() {
}
else
{
// We don't want to update the marking status if a GC pause
// is already underway.
_sts
.
join
()
;
SuspendibleThreadSetJoiner
sts
;
g1h
->
set_marking_complete
();
_sts
.
leave
();
}
// Check if cleanup set the free_regions_coming flag. If it
...
...
@@ -266,11 +265,12 @@ void ConcurrentMarkThread::run() {
// record_concurrent_mark_cleanup_completed() (and, in fact, it's
// not needed any more as the concurrent mark state has been
// already reset).
_sts
.
join
();
if
(
!
cm
()
->
has_aborted
())
{
g1_policy
->
record_concurrent_mark_cleanup_completed
();
{
SuspendibleThreadSetJoiner
sts
;
if
(
!
cm
()
->
has_aborted
())
{
g1_policy
->
record_concurrent_mark_cleanup_completed
();
}
}
_sts
.
leave
();
if
(
cm
()
->
has_aborted
())
{
if
(
G1Log
::
fine
())
{
...
...
@@ -282,30 +282,27 @@ void ConcurrentMarkThread::run() {
// We now want to allow clearing of the marking bitmap to be
// suspended by a collection pause.
_sts
.
join
();
_cm
->
clearNextBitmap
();
_sts
.
leave
();
{
SuspendibleThreadSetJoiner
sts
;
_cm
->
clearNextBitmap
();
}
}
// Update the number of full collections that have been
// completed. This will also notify the FullGCCount_lock in case a
// Java thread is waiting for a full GC to happen (e.g., it
// called System.gc() with +ExplicitGCInvokesConcurrent).
_sts
.
join
();
g1h
->
increment_old_marking_cycles_completed
(
true
/* concurrent */
);
g1h
->
register_concurrent_cycle_end
();
_sts
.
leave
();
{
SuspendibleThreadSetJoiner
sts
;
g1h
->
increment_old_marking_cycles_completed
(
true
/* concurrent */
);
g1h
->
register_concurrent_cycle_end
();
}
}
assert
(
_should_terminate
,
"just checking"
);
terminate
();
}
void
ConcurrentMarkThread
::
yield
()
{
_sts
.
yield
(
"Concurrent Mark"
);
}
void
ConcurrentMarkThread
::
stop
()
{
{
MutexLockerEx
ml
(
Terminator_lock
);
...
...
hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp
浏览文件 @
72ae63a4
...
...
@@ -89,9 +89,6 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
// that started() is set and set in_progress().
bool
during_cycle
()
{
return
started
()
||
in_progress
();
}
// Yield for GC
void
yield
();
// shutdown
void
stop
();
};
...
...
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
72ae63a4
...
...
@@ -92,15 +92,13 @@ size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
// Local to this file.
class
RefineCardTableEntryClosure
:
public
CardTableEntryClosure
{
SuspendibleThreadSet
*
_sts
;
G1RemSet
*
_g1rs
;
ConcurrentG1Refine
*
_cg1r
;
bool
_concurrent
;
public:
RefineCardTableEntryClosure
(
SuspendibleThreadSet
*
sts
,
G1RemSet
*
g1rs
,
RefineCardTableEntryClosure
(
G1RemSet
*
g1rs
,
ConcurrentG1Refine
*
cg1r
)
:
_
sts
(
sts
),
_
g1rs
(
g1rs
),
_cg1r
(
cg1r
),
_concurrent
(
true
)
_g1rs
(
g1rs
),
_cg1r
(
cg1r
),
_concurrent
(
true
)
{}
bool
do_card_ptr
(
jbyte
*
card_ptr
,
uint
worker_i
)
{
bool
oops_into_cset
=
_g1rs
->
refine_card
(
card_ptr
,
worker_i
,
false
);
...
...
@@ -109,7 +107,7 @@ public:
// that point into the collection set.
assert
(
!
oops_into_cset
,
"should be"
);
if
(
_concurrent
&&
_sts
->
should_yield
())
{
if
(
_concurrent
&&
SuspendibleThreadSet
::
should_yield
())
{
// Caller will actually yield.
return
false
;
}
...
...
@@ -2117,8 +2115,7 @@ jint G1CollectedHeap::initialize() {
g1_policy
()
->
init
();
_refine_cte_cl
=
new
RefineCardTableEntryClosure
(
ConcurrentG1RefineThread
::
sts
(),
g1_rem_set
(),
new
RefineCardTableEntryClosure
(
g1_rem_set
(),
concurrent_g1_refine
());
JavaThread
::
dirty_card_queue_set
().
set_closure
(
_refine_cte_cl
);
...
...
@@ -4317,7 +4314,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
// this point does not assume that we are the only GC thread
// running. Note: of course, the actual marking work will
// not start until the safepoint itself is released in
//
ConcurrentGCThread::safepoint_
desynchronize().
//
SuspendibleThreadSet::
desynchronize().
doConcurrentMark
();
}
...
...
hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp
浏览文件 @
72ae63a4
...
...
@@ -77,38 +77,37 @@ void G1StringDedupThread::run() {
break
;
}
// Include this thread in safepoints
stsJoin
();
stat
.
mark_exec
();
// Process the queue
for
(;;)
{
oop
java_string
=
G1StringDedupQueue
::
pop
();
if
(
java_string
==
NULL
)
{
break
;
}
G1StringDedupTable
::
deduplicate
(
java_string
,
stat
);
// Safepoint this thread if needed
if
(
stsShouldYield
())
{
stat
.
mark_block
();
stsYield
(
NULL
);
stat
.
mark_unblock
();
{
// Include thread in safepoints
SuspendibleThreadSetJoiner
sts
;
stat
.
mark_exec
();
// Process the queue
for
(;;)
{
oop
java_string
=
G1StringDedupQueue
::
pop
();
if
(
java_string
==
NULL
)
{
break
;
}
G1StringDedupTable
::
deduplicate
(
java_string
,
stat
);
// Safepoint this thread if needed
if
(
sts
.
should_yield
())
{
stat
.
mark_block
();
sts
.
yield
();
stat
.
mark_unblock
();
}
}
}
G1StringDedupTable
::
trim_entry_cache
();
G1StringDedupTable
::
trim_entry_cache
();
stat
.
mark_done
();
stat
.
mark_done
();
// Print statistics
total_stat
.
add
(
stat
);
print
(
gclog_or_tty
,
stat
,
total_stat
);
// Exclude this thread from safepoints
stsLeave
();
// Print statistics
total_stat
.
add
(
stat
);
print
(
gclog_or_tty
,
stat
,
total_stat
);
}
}
terminate
();
...
...
hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp
浏览文件 @
72ae63a4
...
...
@@ -37,21 +37,10 @@
int
ConcurrentGCThread
::
_CGC_flag
=
CGC_nil
;
SuspendibleThreadSet
ConcurrentGCThread
::
_sts
;
ConcurrentGCThread
::
ConcurrentGCThread
()
:
_should_terminate
(
false
),
_has_terminated
(
false
)
{
_sts
.
initialize
();
};
void
ConcurrentGCThread
::
safepoint_synchronize
()
{
_sts
.
suspend_all
();
}
void
ConcurrentGCThread
::
safepoint_desynchronize
()
{
_sts
.
resume_all
();
}
void
ConcurrentGCThread
::
create_and_start
()
{
if
(
os
::
create_thread
(
this
,
os
::
cgc_thread
))
{
// XXX: need to set this to low priority
...
...
@@ -92,78 +81,6 @@ void ConcurrentGCThread::terminate() {
ThreadLocalStorage
::
set_thread
(
NULL
);
}
void
SuspendibleThreadSet
::
initialize_work
()
{
MutexLocker
x
(
STS_init_lock
);
if
(
!
_initialized
)
{
_m
=
new
Monitor
(
Mutex
::
leaf
,
"SuspendibleThreadSetLock"
,
true
);
_async
=
0
;
_async_stop
=
false
;
_async_stopped
=
0
;
_initialized
=
true
;
}
}
void
SuspendibleThreadSet
::
join
()
{
initialize
();
MutexLockerEx
x
(
_m
,
Mutex
::
_no_safepoint_check_flag
);
while
(
_async_stop
)
_m
->
wait
(
Mutex
::
_no_safepoint_check_flag
);
_async
++
;
assert
(
_async
>
0
,
"Huh."
);
}
void
SuspendibleThreadSet
::
leave
()
{
assert
(
_initialized
,
"Must be initialized."
);
MutexLockerEx
x
(
_m
,
Mutex
::
_no_safepoint_check_flag
);
_async
--
;
assert
(
_async
>=
0
,
"Huh."
);
if
(
_async_stop
)
_m
->
notify_all
();
}
void
SuspendibleThreadSet
::
yield
(
const
char
*
id
)
{
assert
(
_initialized
,
"Must be initialized."
);
if
(
_async_stop
)
{
MutexLockerEx
x
(
_m
,
Mutex
::
_no_safepoint_check_flag
);
if
(
_async_stop
)
{
_async_stopped
++
;
assert
(
_async_stopped
>
0
,
"Huh."
);
if
(
_async_stopped
==
_async
)
{
if
(
ConcGCYieldTimeout
>
0
)
{
double
now
=
os
::
elapsedTime
();
guarantee
((
now
-
_suspend_all_start
)
*
1000.0
<
(
double
)
ConcGCYieldTimeout
,
"Long delay; whodunit?"
);
}
}
_m
->
notify_all
();
while
(
_async_stop
)
_m
->
wait
(
Mutex
::
_no_safepoint_check_flag
);
_async_stopped
--
;
assert
(
_async
>=
0
,
"Huh"
);
_m
->
notify_all
();
}
}
}
void
SuspendibleThreadSet
::
suspend_all
()
{
initialize
();
// If necessary.
if
(
ConcGCYieldTimeout
>
0
)
{
_suspend_all_start
=
os
::
elapsedTime
();
}
MutexLockerEx
x
(
_m
,
Mutex
::
_no_safepoint_check_flag
);
assert
(
!
_async_stop
,
"Only one at a time."
);
_async_stop
=
true
;
while
(
_async_stopped
<
_async
)
_m
->
wait
(
Mutex
::
_no_safepoint_check_flag
);
}
void
SuspendibleThreadSet
::
resume_all
()
{
assert
(
_initialized
,
"Must be initialized."
);
MutexLockerEx
x
(
_m
,
Mutex
::
_no_safepoint_check_flag
);
assert
(
_async_stopped
==
_async
,
"Huh."
);
_async_stop
=
false
;
_m
->
notify_all
();
}
static
void
_sltLoop
(
JavaThread
*
thread
,
TRAPS
)
{
SurrogateLockerThread
*
slt
=
(
SurrogateLockerThread
*
)
thread
;
slt
->
loop
();
...
...
@@ -283,30 +200,3 @@ void SurrogateLockerThread::loop() {
}
assert
(
!
_monitor
.
owned_by_self
(),
"Should unlock before exit."
);
}
// ===== STS Access From Outside CGCT =====
void
ConcurrentGCThread
::
stsYield
(
const
char
*
id
)
{
assert
(
Thread
::
current
()
->
is_ConcurrentGC_thread
(),
"only a conc GC thread can call this"
);
_sts
.
yield
(
id
);
}
bool
ConcurrentGCThread
::
stsShouldYield
()
{
assert
(
Thread
::
current
()
->
is_ConcurrentGC_thread
(),
"only a conc GC thread can call this"
);
return
_sts
.
should_yield
();
}
void
ConcurrentGCThread
::
stsJoin
()
{
assert
(
Thread
::
current
()
->
is_ConcurrentGC_thread
(),
"only a conc GC thread can call this"
);
_sts
.
join
();
}
void
ConcurrentGCThread
::
stsLeave
()
{
assert
(
Thread
::
current
()
->
is_ConcurrentGC_thread
(),
"only a conc GC thread can call this"
);
_sts
.
leave
();
}
hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp
浏览文件 @
72ae63a4
...
...
@@ -26,55 +26,8 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
#include "utilities/macros.hpp"
#i
f INCLUDE_ALL_GCS
#i
nclude "gc_implementation/shared/suspendibleThreadSet.hpp"
#include "runtime/thread.hpp"
#endif // INCLUDE_ALL_GCS
class
VoidClosure
;
// A SuspendibleThreadSet is (obviously) a set of threads that can be
// suspended. A thread can join and later leave the set, and periodically
// yield. If some thread (not in the set) requests, via suspend_all, that
// the threads be suspended, then the requesting thread is blocked until
// all the threads in the set have yielded or left the set. (Threads may
// not enter the set when an attempted suspension is in progress.) The
// suspending thread later calls resume_all, allowing the suspended threads
// to continue.
class
SuspendibleThreadSet
{
Monitor
*
_m
;
int
_async
;
bool
_async_stop
;
int
_async_stopped
;
bool
_initialized
;
double
_suspend_all_start
;
void
initialize_work
();
public:
SuspendibleThreadSet
()
:
_initialized
(
false
)
{}
// Add the current thread to the set. May block if a suspension
// is in progress.
void
join
();
// Removes the current thread from the set.
void
leave
();
// Returns "true" iff an suspension is in progress.
bool
should_yield
()
{
return
_async_stop
;
}
// Suspends the current thread if a suspension is in progress (for
// the duration of the suspension.)
void
yield
(
const
char
*
id
);
// Return when all threads in the set are suspended.
void
suspend_all
();
// Allow suspended threads to resume.
void
resume_all
();
// Redundant initializations okay.
void
initialize
()
{
// Double-check dirty read idiom.
if
(
!
_initialized
)
initialize_work
();
}
};
class
ConcurrentGCThread
:
public
NamedThread
{
friend
class
VMStructs
;
...
...
@@ -96,9 +49,6 @@ protected:
static
int
set_CGC_flag
(
int
b
)
{
return
_CGC_flag
|=
b
;
}
static
int
reset_CGC_flag
(
int
b
)
{
return
_CGC_flag
&=
~
b
;
}
// All instances share this one set.
static
SuspendibleThreadSet
_sts
;
// Create and start the thread (setting it's priority high.)
void
create_and_start
();
...
...
@@ -121,25 +71,6 @@ public:
// Tester
bool
is_ConcurrentGC_thread
()
const
{
return
true
;
}
static
void
safepoint_synchronize
();
static
void
safepoint_desynchronize
();
// All overridings should probably do _sts::yield, but we allow
// overriding for distinguished debugging messages. Default is to do
// nothing.
virtual
void
yield
()
{}
bool
should_yield
()
{
return
_sts
.
should_yield
();
}
// they are prefixed by sts since there are already yield() and
// should_yield() (non-static) methods in this class and it was an
// easy way to differentiate them.
static
void
stsYield
(
const
char
*
id
);
static
bool
stsShouldYield
();
static
void
stsJoin
();
static
void
stsLeave
();
};
// The SurrogateLockerThread is used by concurrent GC threads for
...
...
hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp
0 → 100644
浏览文件 @
72ae63a4
/*
* Copyright (c) 2014, 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.
*
*/
#include "precompiled.hpp"
#include "gc_implementation/shared/suspendibleThreadSet.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
uint
SuspendibleThreadSet
::
_nthreads
=
0
;
uint
SuspendibleThreadSet
::
_nthreads_stopped
=
0
;
bool
SuspendibleThreadSet
::
_suspend_all
=
false
;
double
SuspendibleThreadSet
::
_suspend_all_start
=
0.0
;
void
SuspendibleThreadSet
::
join
()
{
MonitorLockerEx
ml
(
STS_lock
,
Mutex
::
_no_safepoint_check_flag
);
while
(
_suspend_all
)
{
ml
.
wait
(
Mutex
::
_no_safepoint_check_flag
);
}
_nthreads
++
;
}
void
SuspendibleThreadSet
::
leave
()
{
MonitorLockerEx
ml
(
STS_lock
,
Mutex
::
_no_safepoint_check_flag
);
assert
(
_nthreads
>
0
,
"Invalid"
);
_nthreads
--
;
if
(
_suspend_all
)
{
ml
.
notify_all
();
}
}
void
SuspendibleThreadSet
::
yield
()
{
if
(
_suspend_all
)
{
MonitorLockerEx
ml
(
STS_lock
,
Mutex
::
_no_safepoint_check_flag
);
if
(
_suspend_all
)
{
_nthreads_stopped
++
;
if
(
_nthreads_stopped
==
_nthreads
)
{
if
(
ConcGCYieldTimeout
>
0
)
{
double
now
=
os
::
elapsedTime
();
guarantee
((
now
-
_suspend_all_start
)
*
1000.0
<
(
double
)
ConcGCYieldTimeout
,
"Long delay"
);
}
}
ml
.
notify_all
();
while
(
_suspend_all
)
{
ml
.
wait
(
Mutex
::
_no_safepoint_check_flag
);
}
assert
(
_nthreads_stopped
>
0
,
"Invalid"
);
_nthreads_stopped
--
;
ml
.
notify_all
();
}
}
}
void
SuspendibleThreadSet
::
synchronize
()
{
assert
(
Thread
::
current
()
->
is_VM_thread
(),
"Must be the VM thread"
);
if
(
ConcGCYieldTimeout
>
0
)
{
_suspend_all_start
=
os
::
elapsedTime
();
}
MonitorLockerEx
ml
(
STS_lock
,
Mutex
::
_no_safepoint_check_flag
);
assert
(
!
_suspend_all
,
"Only one at a time"
);
_suspend_all
=
true
;
while
(
_nthreads_stopped
<
_nthreads
)
{
ml
.
wait
(
Mutex
::
_no_safepoint_check_flag
);
}
}
void
SuspendibleThreadSet
::
desynchronize
()
{
assert
(
Thread
::
current
()
->
is_VM_thread
(),
"Must be the VM thread"
);
MonitorLockerEx
ml
(
STS_lock
,
Mutex
::
_no_safepoint_check_flag
);
assert
(
_nthreads_stopped
==
_nthreads
,
"Invalid"
);
_suspend_all
=
false
;
ml
.
notify_all
();
}
hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp
0 → 100644
浏览文件 @
72ae63a4
/*
* Copyright (c) 2014, 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.
*
*/
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
#include "memory/allocation.hpp"
// A SuspendibleThreadSet is a set of threads that can be suspended.
// A thread can join and later leave the set, and periodically yield.
// If some thread (not in the set) requests, via synchronize(), that
// the threads be suspended, then the requesting thread is blocked
// until all the threads in the set have yielded or left the set. Threads
// may not enter the set when an attempted suspension is in progress. The
// suspending thread later calls desynchronize(), allowing the suspended
// threads to continue.
class
SuspendibleThreadSet
:
public
AllStatic
{
private:
static
uint
_nthreads
;
static
uint
_nthreads_stopped
;
static
bool
_suspend_all
;
static
double
_suspend_all_start
;
public:
// Add the current thread to the set. May block if a suspension is in progress.
static
void
join
();
// Removes the current thread from the set.
static
void
leave
();
// Returns true if an suspension is in progress.
static
bool
should_yield
()
{
return
_suspend_all
;
}
// Suspends the current thread if a suspension is in progress.
static
void
yield
();
// Returns when all threads in the set are suspended.
static
void
synchronize
();
// Resumes all suspended threads in the set.
static
void
desynchronize
();
};
class
SuspendibleThreadSetJoiner
:
public
StackObj
{
public:
SuspendibleThreadSetJoiner
()
{
SuspendibleThreadSet
::
join
();
}
~
SuspendibleThreadSetJoiner
()
{
SuspendibleThreadSet
::
leave
();
}
bool
should_yield
()
{
return
SuspendibleThreadSet
::
should_yield
();
}
void
yield
()
{
SuspendibleThreadSet
::
yield
();
}
};
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
hotspot/src/share/vm/runtime/mutexLocker.cpp
浏览文件 @
72ae63a4
...
...
@@ -69,7 +69,7 @@ Monitor* Safepoint_lock = NULL;
Monitor
*
SerializePage_lock
=
NULL
;
Monitor
*
Threads_lock
=
NULL
;
Monitor
*
CGC_lock
=
NULL
;
M
utex
*
STS_init_lock
=
NULL
;
M
onitor
*
STS_lock
=
NULL
;
Monitor
*
SLT_lock
=
NULL
;
Monitor
*
iCMS_lock
=
NULL
;
Monitor
*
FullGCCount_lock
=
NULL
;
...
...
@@ -173,7 +173,7 @@ void mutex_init() {
def
(
tty_lock
,
Mutex
,
event
,
true
);
// allow to lock in VM
def
(
CGC_lock
,
Monitor
,
special
,
true
);
// coordinate between fore- and background GC
def
(
STS_
init_lock
,
Mutex
,
leaf
,
true
);
def
(
STS_
lock
,
Monitor
,
leaf
,
true
);
if
(
UseConcMarkSweepGC
)
{
def
(
iCMS_lock
,
Monitor
,
special
,
true
);
// CMS incremental mode start/stop notification
}
...
...
hotspot/src/share/vm/runtime/mutexLocker.hpp
浏览文件 @
72ae63a4
...
...
@@ -79,7 +79,7 @@ extern Monitor* Threads_lock; // a lock on the Threads table
// (also used by Safepoints too to block threads creation/destruction)
extern
Monitor
*
CGC_lock
;
// used for coordination between
// fore- & background GC threads.
extern
M
utex
*
STS_init_lock
;
// coordinate initialization of SuspendibleThreadSets
.
extern
M
onitor
*
STS_lock
;
// used for joining/leaving SuspendibleThreadSet
.
extern
Monitor
*
SLT_lock
;
// used in CMS GC for acquiring PLL
extern
Monitor
*
iCMS_lock
;
// CMS incremental mode start/stop notification
extern
Monitor
*
FullGCCount_lock
;
// in support of "concurrent" full gc
...
...
hotspot/src/share/vm/runtime/safepoint.cpp
浏览文件 @
72ae63a4
...
...
@@ -75,7 +75,7 @@
#endif
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/shared/
concurrentGCThread
.hpp"
#include "gc_implementation/shared/
suspendibleThreadSet
.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
...
...
@@ -110,7 +110,7 @@ void SafepointSynchronize::begin() {
// more-general mechanism below. DLD (01/05).
ConcurrentMarkSweepThread
::
synchronize
(
false
);
}
else
if
(
UseG1GC
)
{
ConcurrentGCThread
::
safepoint_
synchronize
();
SuspendibleThreadSet
::
synchronize
();
}
#endif // INCLUDE_ALL_GCS
...
...
@@ -486,7 +486,7 @@ void SafepointSynchronize::end() {
if
(
UseConcMarkSweepGC
)
{
ConcurrentMarkSweepThread
::
desynchronize
(
false
);
}
else
if
(
UseG1GC
)
{
ConcurrentGCThread
::
safepoint_
desynchronize
();
SuspendibleThreadSet
::
desynchronize
();
}
#endif // INCLUDE_ALL_GCS
// record this time so VMThread can keep track how much time has elapsed
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录