60 // : // do stuff with 'jt'...
61 //
62 // JVM/TI oop example (this one should be very rare):
63 // oop thread_obj = ...;
64 // :
65 // JavaThread *jt = NULL;
66 // ThreadsListHandle tlh;
67 // jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt);
68 // if (err != JVMTI_ERROR_NONE) {
69 // return err;
70 // }
71 // : // do stuff with 'jt'...
72 //
73 // A JavaThread * that is included in the ThreadsList that is held by
74 // a ThreadsListHandle is protected as long as the ThreadsListHandle
75 // remains in scope. The target JavaThread * may have logically exited,
76 // but that target JavaThread * will not be deleted until it is no
77 // longer protected by a ThreadsListHandle.
78
79
80 // A fast list of JavaThreads.
81 //
82 class ThreadsList : public CHeapObj<mtThread> {
83 friend class ScanHazardPtrGatherProtectedThreadsClosure;
84 friend class Threads;
85
86 const uint _length;
87 ThreadsList* _next_list;
88 JavaThread *const *const _threads;
89
90 template <class T>
91 void threads_do_dispatch(T *cl, JavaThread *const thread) const;
92
93 ThreadsList *next_list() const { return _next_list; }
94 void set_next_list(ThreadsList *list) { _next_list = list; }
95
96 public:
97 ThreadsList(int entries);
98 ~ThreadsList();
99
100 template <class T>
101 void threads_do(T *cl) const;
102
103 uint length() const { return _length; }
104
105 JavaThread *const thread_at(uint i) const { return _threads[i]; }
106
107 JavaThread *const *threads() const { return _threads; }
108
109 // Returns -1 if target is not found.
110 int find_index_of_JavaThread(JavaThread* target);
111 JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
112 bool includes(const JavaThread * const p) const;
113
114 static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
115 static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
116 };
117
118 // Linked list of ThreadsLists to support nested ThreadsListHandles.
119 class NestedThreadsList : public CHeapObj<mtThread> {
120 ThreadsList*const _t_list;
121 NestedThreadsList* _next;
122
123 public:
124 NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) {
125 assert(Threads_lock->owned_by_self(),
126 "must own Threads_lock for saved t_list to be valid.");
127 }
128
129 ThreadsList* t_list() { return _t_list; }
130 NestedThreadsList* next() { return _next; }
131 void set_next(NestedThreadsList* value) { _next = value; }
132 };
133
134 // A helper to optionally set the hazard ptr in ourself. This helper can
135 // be used by ourself or by another thread. If the hazard ptr is set(),
|
60 // : // do stuff with 'jt'...
61 //
62 // JVM/TI oop example (this one should be very rare):
63 // oop thread_obj = ...;
64 // :
65 // JavaThread *jt = NULL;
66 // ThreadsListHandle tlh;
67 // jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt);
68 // if (err != JVMTI_ERROR_NONE) {
69 // return err;
70 // }
71 // : // do stuff with 'jt'...
72 //
73 // A JavaThread * that is included in the ThreadsList that is held by
74 // a ThreadsListHandle is protected as long as the ThreadsListHandle
75 // remains in scope. The target JavaThread * may have logically exited,
76 // but that target JavaThread * will not be deleted until it is no
77 // longer protected by a ThreadsListHandle.
78
79
80 // SMR Support for the Threads class.
81 //
82 class ThreadsSMRSupport : AllStatic {
83 // The coordination between ThreadsSMRSupport::release_stable_list() and
84 // ThreadsSMRSupport::smr_delete() uses the smr_delete_lock in order to
85 // reduce the traffic on the Threads_lock.
86 static Monitor* _smr_delete_lock;
87 // The '_cnt', '_max' and '_times" fields are enabled via
88 // -XX:+EnableThreadSMRStatistics (see thread.cpp for a
89 // description about each field):
90 static uint _smr_delete_lock_wait_cnt;
91 static uint _smr_delete_lock_wait_max;
92 // The smr_delete_notify flag is used for proper double-check
93 // locking in order to reduce the traffic on the smr_delete_lock.
94 static volatile uint _smr_delete_notify;
95 static volatile uint _smr_deleted_thread_cnt;
96 static volatile uint _smr_deleted_thread_time_max;
97 static volatile uint _smr_deleted_thread_times;
98 static ThreadsList* volatile _smr_java_thread_list;
99 static uint64_t _smr_java_thread_list_alloc_cnt;
100 static uint64_t _smr_java_thread_list_free_cnt;
101 static uint _smr_java_thread_list_max;
102 static uint _smr_nested_thread_list_max;
103 static volatile uint _smr_tlh_cnt;
104 static volatile uint _smr_tlh_time_max;
105 static volatile uint _smr_tlh_times;
106 static ThreadsList* _smr_to_delete_list;
107 static uint _smr_to_delete_list_cnt;
108 static uint _smr_to_delete_list_max;
109
110 static ThreadsList *acquire_stable_list_fast_path(Thread *self);
111 static ThreadsList *acquire_stable_list_nested_path(Thread *self);
112 static void add_smr_deleted_thread_times(uint add_value);
113 static void add_smr_tlh_times(uint add_value);
114 static void clear_smr_delete_notify();
115 static void inc_smr_deleted_thread_cnt();
116 static void inc_smr_java_thread_list_alloc_cnt();
117 static void inc_smr_tlh_cnt();
118 static bool is_a_protected_JavaThread(JavaThread *thread);
119 static void release_stable_list_fast_path(Thread *self);
120 static void release_stable_list_nested_path(Thread *self);
121 static void release_stable_list_wake_up(char *log_str);
122 static void set_smr_delete_notify();
123 static Monitor* smr_delete_lock() { return _smr_delete_lock; }
124 static bool smr_delete_notify();
125 static void smr_free_list(ThreadsList* threads);
126 static void update_smr_deleted_thread_time_max(uint new_value);
127 static void update_smr_java_thread_list_max(uint new_value);
128 static void update_smr_tlh_time_max(uint new_value);
129 static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list);
130
131 public:
132 static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
133 static void add_thread(JavaThread *thread);
134 static ThreadsList* get_smr_java_thread_list();
135 static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);
136 static void release_stable_list(Thread *self);
137 static void remove_thread(JavaThread *thread);
138 static void smr_delete(JavaThread *thread);
139 static void update_smr_tlh_stats(uint millis);
140
141 // Logging and printing support:
142 static void log_smr_statistics();
143 static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list);
144 static void print_smr_info_on(outputStream* st);
145 };
146
147 // A fast list of JavaThreads.
148 //
149 class ThreadsList : public CHeapObj<mtThread> {
150 friend class ThreadsSMRSupport; // for next_list(), set_next_list() access
151
152 const uint _length;
153 ThreadsList* _next_list;
154 JavaThread *const *const _threads;
155
156 template <class T>
157 void threads_do_dispatch(T *cl, JavaThread *const thread) const;
158
159 ThreadsList *next_list() const { return _next_list; }
160 void set_next_list(ThreadsList *list) { _next_list = list; }
161
162 static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
163 static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
164
165 public:
166 ThreadsList(int entries);
167 ~ThreadsList();
168
169 template <class T>
170 void threads_do(T *cl) const;
171
172 uint length() const { return _length; }
173
174 JavaThread *const thread_at(uint i) const { return _threads[i]; }
175
176 JavaThread *const *threads() const { return _threads; }
177
178 // Returns -1 if target is not found.
179 int find_index_of_JavaThread(JavaThread* target);
180 JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
181 bool includes(const JavaThread * const p) const;
182 };
183
184 // Linked list of ThreadsLists to support nested ThreadsListHandles.
185 class NestedThreadsList : public CHeapObj<mtThread> {
186 ThreadsList*const _t_list;
187 NestedThreadsList* _next;
188
189 public:
190 NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) {
191 assert(Threads_lock->owned_by_self(),
192 "must own Threads_lock for saved t_list to be valid.");
193 }
194
195 ThreadsList* t_list() { return _t_list; }
196 NestedThreadsList* next() { return _next; }
197 void set_next(NestedThreadsList* value) { _next = value; }
198 };
199
200 // A helper to optionally set the hazard ptr in ourself. This helper can
201 // be used by ourself or by another thread. If the hazard ptr is set(),
|