mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8221102: Allow GC threads to participate in threads claiming protocol
Expand claim counter from 1bit to uintx, with rare overflow handling. Reviewed-by: tschatzl, rkennke
This commit is contained in:
parent
4269bb40ac
commit
e7e00f7ae0
9 changed files with 259 additions and 69 deletions
|
@ -338,9 +338,8 @@ class Thread: public ThreadShadow {
|
|||
// Point to the last handle mark
|
||||
HandleMark* _last_handle_mark;
|
||||
|
||||
// The parity of the last strong_roots iteration in which this thread was
|
||||
// claimed as a task.
|
||||
int _oops_do_parity;
|
||||
// Claim value for parallel iteration over threads.
|
||||
uintx _threads_do_token;
|
||||
|
||||
// Support for GlobalCounter
|
||||
private:
|
||||
|
@ -647,27 +646,28 @@ class Thread: public ThreadShadow {
|
|||
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
|
||||
virtual void oops_do(OopClosure* f, CodeBlobClosure* cf);
|
||||
|
||||
// Handles the parallel case for the method below.
|
||||
// Handles the parallel case for claim_threads_do.
|
||||
private:
|
||||
bool claim_oops_do_par_case(int collection_parity);
|
||||
bool claim_par_threads_do(uintx claim_token);
|
||||
public:
|
||||
// Requires that "collection_parity" is that of the current roots
|
||||
// iteration. If "is_par" is false, sets the parity of "this" to
|
||||
// "collection_parity", and returns "true". If "is_par" is true,
|
||||
// uses an atomic instruction to set the current threads parity to
|
||||
// "collection_parity", if it is not already. Returns "true" iff the
|
||||
// Requires that "claim_token" is that of the current iteration.
|
||||
// If "is_par" is false, sets the token of "this" to
|
||||
// "claim_token", and returns "true". If "is_par" is true,
|
||||
// uses an atomic instruction to set the current thread's token to
|
||||
// "claim_token", if it is not already. Returns "true" iff the
|
||||
// calling thread does the update, this indicates that the calling thread
|
||||
// has claimed the thread's stack as a root group in the current
|
||||
// collection.
|
||||
bool claim_oops_do(bool is_par, int collection_parity) {
|
||||
// has claimed the thread in the current iteration.
|
||||
bool claim_threads_do(bool is_par, uintx claim_token) {
|
||||
if (!is_par) {
|
||||
_oops_do_parity = collection_parity;
|
||||
_threads_do_token = claim_token;
|
||||
return true;
|
||||
} else {
|
||||
return claim_oops_do_par_case(collection_parity);
|
||||
return claim_par_threads_do(claim_token);
|
||||
}
|
||||
}
|
||||
|
||||
uintx threads_do_token() const { return _threads_do_token; }
|
||||
|
||||
// jvmtiRedefineClasses support
|
||||
void metadata_handles_do(void f(Metadata*));
|
||||
|
||||
|
@ -750,7 +750,6 @@ protected:
|
|||
Monitor* owned_locks() const { return _owned_locks; }
|
||||
bool owns_locks() const { return owned_locks() != NULL; }
|
||||
bool owns_locks_but_compiled_lock() const;
|
||||
int oops_do_parity() const { return _oops_do_parity; }
|
||||
|
||||
// Deadlock detection
|
||||
bool allow_allocation() { return _allow_allocation_count == 0; }
|
||||
|
@ -2223,7 +2222,7 @@ class Threads: AllStatic {
|
|||
static int _number_of_threads;
|
||||
static int _number_of_non_daemon_threads;
|
||||
static int _return_code;
|
||||
static int _thread_claim_parity;
|
||||
static uintx _thread_claim_token;
|
||||
#ifdef ASSERT
|
||||
static bool _vm_complete;
|
||||
#endif
|
||||
|
@ -2256,21 +2255,23 @@ class Threads: AllStatic {
|
|||
// Does not include JNI_VERSION_1_1
|
||||
static jboolean is_supported_jni_version(jint version);
|
||||
|
||||
// The "thread claim parity" provides a way for threads to be claimed
|
||||
// The "thread claim token" provides a way for threads to be claimed
|
||||
// by parallel worker tasks.
|
||||
//
|
||||
// Each thread contains a "parity" field. A task will claim the
|
||||
// thread only if its parity field is the same as the global parity,
|
||||
// which is updated by calling change_thread_claim_parity().
|
||||
// Each thread contains a "token" field. A task will claim the
|
||||
// thread only if its token is different from the global token,
|
||||
// which is updated by calling change_thread_claim_token(). When
|
||||
// a thread is claimed, it's token is set to the global token value
|
||||
// so other threads in the same iteration pass won't claim it.
|
||||
//
|
||||
// For this to work change_thread_claim_parity() needs to be called
|
||||
// For this to work change_thread_claim_token() needs to be called
|
||||
// exactly once in sequential code before starting parallel tasks
|
||||
// that should claim threads.
|
||||
//
|
||||
// New threads get their parity set to 0 and change_thread_claim_parity()
|
||||
// never sets the global parity to 0.
|
||||
static int thread_claim_parity() { return _thread_claim_parity; }
|
||||
static void change_thread_claim_parity();
|
||||
// New threads get their token set to 0 and change_thread_claim_token()
|
||||
// never sets the global token to 0.
|
||||
static uintx thread_claim_token() { return _thread_claim_token; }
|
||||
static void change_thread_claim_token();
|
||||
static void assert_all_threads_claimed() NOT_DEBUG_RETURN;
|
||||
|
||||
// Apply "f->do_oop" to all root oops in all threads.
|
||||
|
@ -2324,6 +2325,8 @@ class Threads: AllStatic {
|
|||
|
||||
// Deoptimizes all frames tied to marked nmethods
|
||||
static void deoptimized_wrt_marked_nmethods();
|
||||
|
||||
struct Test; // For private gtest access.
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue