comparison src/share/vm/services/memTrackWorker.cpp @ 10096:35f8765422b9

8010151: nsk/regression/b6653214 fails "assert(snapshot != NULL) failed: Worker should not be started" Summary: Fixed a racing condition when shutting down NMT while worker thread is being started, also fixed a few mis-declared volatile pointers. Reviewed-by: dholmes, dlong
author zgu
date Wed, 10 Apr 2013 08:55:50 -0400
parents 4102b59539ce
children 9758d9f36299
comparison
equal deleted inserted replaced
9066:09b0d3e9ba6c 10096:35f8765422b9
37 _recorder_list = _recorder_list->next(); 37 _recorder_list = _recorder_list->next();
38 MemTracker::release_thread_recorder(tmp); 38 MemTracker::release_thread_recorder(tmp);
39 } 39 }
40 } 40 }
41 41
42 MemTrackWorker::MemTrackWorker() { 42 MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) {
43 // create thread uses cgc thread type for now. We should revisit 43 // create thread uses cgc thread type for now. We should revisit
44 // the option, or create new thread type. 44 // the option, or create new thread type.
45 _has_error = !os::create_thread(this, os::cgc_thread); 45 _has_error = !os::create_thread(this, os::cgc_thread);
46 set_name("MemTrackWorker", 0); 46 set_name("MemTrackWorker", 0);
47 47
86 86
87 void MemTrackWorker::run() { 87 void MemTrackWorker::run() {
88 assert(MemTracker::is_on(), "native memory tracking is off"); 88 assert(MemTracker::is_on(), "native memory tracking is off");
89 this->initialize_thread_local_storage(); 89 this->initialize_thread_local_storage();
90 this->record_stack_base_and_size(); 90 this->record_stack_base_and_size();
91 MemSnapshot* snapshot = MemTracker::get_snapshot(); 91 assert(_snapshot != NULL, "Worker should not be started");
92 assert(snapshot != NULL, "Worker should not be started");
93 MemRecorder* rec; 92 MemRecorder* rec;
94 unsigned long processing_generation = 0; 93 unsigned long processing_generation = 0;
95 bool worker_idle = false; 94 bool worker_idle = false;
96 95
97 while (!MemTracker::shutdown_in_progress()) { 96 while (!MemTracker::shutdown_in_progress()) {
107 worker_idle = false; 106 worker_idle = false;
108 MemTracker::set_current_processing_generation(processing_generation); 107 MemTracker::set_current_processing_generation(processing_generation);
109 } 108 }
110 109
111 // merge the recorder into staging area 110 // merge the recorder into staging area
112 if (!snapshot->merge(rec)) { 111 if (!_snapshot->merge(rec)) {
113 MemTracker::shutdown(MemTracker::NMT_out_of_memory); 112 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
114 } else { 113 } else {
115 NOT_PRODUCT(_merge_count ++;) 114 NOT_PRODUCT(_merge_count ++;)
116 } 115 }
117 MemTracker::release_thread_recorder(rec); 116 MemTracker::release_thread_recorder(rec);
130 129
131 // done with this generation, increment _head pointer 130 // done with this generation, increment _head pointer
132 _head = (_head + 1) % MAX_GENERATIONS; 131 _head = (_head + 1) % MAX_GENERATIONS;
133 } 132 }
134 // promote this generation data to snapshot 133 // promote this generation data to snapshot
135 if (!snapshot->promote(number_of_classes)) { 134 if (!_snapshot->promote(number_of_classes)) {
136 // failed to promote, means out of memory 135 // failed to promote, means out of memory
137 MemTracker::shutdown(MemTracker::NMT_out_of_memory); 136 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
138 } 137 }
139 } else { 138 } else {
140 // worker thread is idle 139 // worker thread is idle
141 worker_idle = true; 140 worker_idle = true;
142 MemTracker::report_worker_idle(); 141 MemTracker::report_worker_idle();
143 snapshot->wait(1000); 142 _snapshot->wait(1000);
144 ThreadCritical tc; 143 ThreadCritical tc;
145 // check if more data arrived 144 // check if more data arrived
146 if (!_gen[_head].has_more_recorder()) { 145 if (!_gen[_head].has_more_recorder()) {
147 _gen[_head].add_recorders(MemTracker::get_pending_recorders()); 146 _gen[_head].add_recorders(MemTracker::get_pending_recorders());
148 } 147 }