41 uint processor_id) :
42 _manager(manager),
43 _processor_id(processor_id),
44 _time_stamps(NULL),
45 _time_stamp_index(0)
46 {
47 set_id(which);
48 set_name("%s#%d", manager->group_name(), which);
49 }
50
51 GCTaskThread::~GCTaskThread() {
52 if (_time_stamps != NULL) {
53 FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
54 }
55 }
56
57 GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
58 guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
59 if (_time_stamps == NULL) {
60 // We allocate the _time_stamps array lazily since logging can be enabled dynamically
61 GCTaskTimeStamp* time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
62 void* old = Atomic::cmpxchg_ptr(time_stamps, &_time_stamps, NULL);
63 if (old != NULL) {
64 // Someone already setup the time stamps
65 FREE_C_HEAP_ARRAY(GCTaskTimeStamp, time_stamps);
66 }
67 }
68
69 return &(_time_stamps[index]);
70 }
71
72 void GCTaskThread::print_task_time_stamps() {
73 assert(log_is_enabled(Debug, gc, task, time), "Sanity");
74
75 // Since _time_stamps is now lazily allocated we need to check that it
76 // has in fact been allocated when calling this function.
77 if (_time_stamps != NULL) {
78 log_debug(gc, task, time)("GC-Thread %u entries: %d", id(), _time_stamp_index);
79 for(uint i=0; i<_time_stamp_index; i++) {
80 GCTaskTimeStamp* time_stamp = time_stamp_at(i);
81 log_debug(gc, task, time)("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]",
82 time_stamp->name(),
83 time_stamp->entry_time(),
84 time_stamp->exit_time());
85 }
86
123 // This will block until there is a task to be gotten.
124 GCTask* task = manager()->get_task(which());
125 GCIdMark gc_id_mark(task->gc_id());
126 // Record if this is an idle task for later use.
127 bool is_idle_task = task->is_idle_task();
128 // In case the update is costly
129 if (log_is_enabled(Debug, gc, task, time)) {
130 timer.update();
131 }
132
133 jlong entry_time = timer.ticks();
134 char* name = task->name();
135
136 // If this is the barrier task, it can be destroyed
137 // by the GC task manager once the do_it() executes.
138 task->do_it(manager(), which());
139
140 // Use the saved value of is_idle_task because references
141 // using "task" are not reliable for the barrier task.
142 if (!is_idle_task) {
143 manager()->note_completion(which());
144
145 if (log_is_enabled(Debug, gc, task, time)) {
146 timer.update();
147
148 GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index);
149
150 time_stamp->set_name(name);
151 time_stamp->set_entry_time(entry_time);
152 time_stamp->set_exit_time(timer.ticks());
153
154 // Update the index after we have set up the entry correctly since
155 // GCTaskThread::print_task_time_stamps() may read this value concurrently.
156 _time_stamp_index++;
157 }
158 } else {
159 // idle tasks complete outside the normal accounting
160 // so that a task can complete without waiting for idle tasks.
161 // They have to be terminated separately.
162 IdleGCTask::destroy((IdleGCTask*)task);
163 set_is_working(true);
164 }
165
166 // Check if we should release our inner resources.
167 if (manager()->should_release_resources(which())) {
168 manager()->note_release(which());
169 break;
170 }
171 }
172 }
173 }
|
41 uint processor_id) :
42 _manager(manager),
43 _processor_id(processor_id),
44 _time_stamps(NULL),
45 _time_stamp_index(0)
46 {
47 set_id(which);
48 set_name("%s#%d", manager->group_name(), which);
49 }
50
51 GCTaskThread::~GCTaskThread() {
52 if (_time_stamps != NULL) {
53 FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
54 }
55 }
56
57 GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
58 guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
59 if (_time_stamps == NULL) {
60 // We allocate the _time_stamps array lazily since logging can be enabled dynamically
61 _time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
62 }
63
64 return &(_time_stamps[index]);
65 }
66
67 void GCTaskThread::print_task_time_stamps() {
68 assert(log_is_enabled(Debug, gc, task, time), "Sanity");
69
70 // Since _time_stamps is now lazily allocated we need to check that it
71 // has in fact been allocated when calling this function.
72 if (_time_stamps != NULL) {
73 log_debug(gc, task, time)("GC-Thread %u entries: %d", id(), _time_stamp_index);
74 for(uint i=0; i<_time_stamp_index; i++) {
75 GCTaskTimeStamp* time_stamp = time_stamp_at(i);
76 log_debug(gc, task, time)("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]",
77 time_stamp->name(),
78 time_stamp->entry_time(),
79 time_stamp->exit_time());
80 }
81
118 // This will block until there is a task to be gotten.
119 GCTask* task = manager()->get_task(which());
120 GCIdMark gc_id_mark(task->gc_id());
121 // Record if this is an idle task for later use.
122 bool is_idle_task = task->is_idle_task();
123 // In case the update is costly
124 if (log_is_enabled(Debug, gc, task, time)) {
125 timer.update();
126 }
127
128 jlong entry_time = timer.ticks();
129 char* name = task->name();
130
131 // If this is the barrier task, it can be destroyed
132 // by the GC task manager once the do_it() executes.
133 task->do_it(manager(), which());
134
135 // Use the saved value of is_idle_task because references
136 // using "task" are not reliable for the barrier task.
137 if (!is_idle_task) {
138 if (log_is_enabled(Debug, gc, task, time)) {
139 timer.update();
140
141 GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index);
142
143 time_stamp->set_name(name);
144 time_stamp->set_entry_time(entry_time);
145 time_stamp->set_exit_time(timer.ticks());
146 _time_stamp_index++;
147 }
148 manager()->note_completion(which());
149 } else {
150 // idle tasks complete outside the normal accounting
151 // so that a task can complete without waiting for idle tasks.
152 // They have to be terminated separately.
153 IdleGCTask::destroy((IdleGCTask*)task);
154 set_is_working(true);
155 }
156
157 // Check if we should release our inner resources.
158 if (manager()->should_release_resources(which())) {
159 manager()->note_release(which());
160 break;
161 }
162 }
163 }
164 }
|