void SolarisAttachOperation::complete(jint res, bufferedStream* st) { if (this->socket() >= 0) { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or // java_suspend_self() via check_and_wait_while_suspended() // write operation result char msg[32]; sprintf(msg, "%d\n", res); int rc = write_fully(this->socket(), msg, strlen(msg)); // write any result data if (rc == 0) { write_fully(this->socket(), (char*) st->base(), st->size()); ::shutdown(this->socket(), 2); } // close socket and we're done ::close(this->socket()); // were we externally suspended while we were waiting? thread->check_and_wait_while_suspended(); } delete this; }
int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread,"attach listener initialization"); int ret_code = LinuxAttachListener::init(); return ret_code; }
AttachOperation* AttachListener::dequeue() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread,"attach listener dequeue"); AttachOperation* op = LinuxAttachListener::dequeue(); return op; }
void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { while (true) { bool sensors_changed = false; bool has_jvmti_events = false; bool has_gc_notification_event = false; bool has_dcmd_notification_event = false; JvmtiDeferredEvent jvmti_event; { // Need state transition ThreadBlockInVM so that this thread // will be handled by safepoint correctly when this thread is // notified at a safepoint. // This ThreadBlockInVM object is not also considered to be // suspend-equivalent because ServiceThread is not visible to // external suspension. ThreadBlockInVM tbivm(jt); MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) && !(has_jvmti_events = JvmtiDeferredEventQueue::has_events()) && !(has_gc_notification_event = GCNotifier::has_event()) && !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification())) { // wait until one of the sensors has pending requests, or there is a // pending JVMTI event or JMX GC notification to post Service_lock->wait(Mutex::_no_safepoint_check_flag); } if (has_jvmti_events) { jvmti_event = JvmtiDeferredEventQueue::dequeue(); } } if (has_jvmti_events) { jvmti_event.post(); } if (sensors_changed) { LowMemoryDetector::process_sensor_changes(jt); } if(has_gc_notification_event) { GCNotifier::sendNotification(CHECK); } if(has_dcmd_notification_event) { DCmdFactory::send_notification(CHECK); } } }
AttachOperation* AttachListener::dequeue() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or // java_suspend_self() via check_and_wait_while_suspended() AttachOperation* op = Win32AttachListener::dequeue(); // were we externally suspended while we were waiting? thread->check_and_wait_while_suspended(); return op; }
int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or // java_suspend_self() int ret_code = SolarisAttachListener::init(); // were we externally suspended while we were waiting? thread->check_and_wait_while_suspended(); return ret_code; }
void LowMemoryDetector::low_memory_detector_thread_entry(JavaThread* jt, TRAPS) { while (true) { bool sensors_changed = false; { // _no_safepoint_check_flag is used here as LowMemory_lock is a // special lock and the VMThread may acquire this lock at safepoint. // Need state transition ThreadBlockInVM so that this thread // will be handled by safepoint correctly when this thread is // notified at a safepoint. // This ThreadBlockInVM object is not also considered to be // suspend-equivalent because LowMemoryDetector threads are // not visible to external suspension. ThreadBlockInVM tbivm(jt); MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); while (!(sensors_changed = has_pending_requests())) { // wait until one of the sensors has pending requests LowMemory_lock->wait(Mutex::_no_safepoint_check_flag); } } { ResourceMark rm(THREAD); HandleMark hm(THREAD); // No need to hold LowMemory_lock to call out to Java int num_memory_pools = MemoryService::num_memory_pools(); for (int i = 0; i < num_memory_pools; i++) { MemoryPool* pool = MemoryService::get_memory_pool(i); SensorInfo* sensor = pool->usage_sensor(); SensorInfo* gc_sensor = pool->gc_usage_sensor(); if (sensor != NULL && sensor->has_pending_requests()) { sensor->process_pending_requests(CHECK); } if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { gc_sensor->process_pending_requests(CHECK); } } } } }
void LinuxAttachOperation::complete(jint result, bufferedStream* st) { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread,"complete attach operation"); // write operation result char msg[32]; sprintf(msg, "%d\n", result); int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg)); // write any result data if (rc == 0) { LinuxAttachListener::write_fully(this->socket(), (char*) st->base(), st->size()); VM_ATTACH_SHUTDOWN(this->socket(),2); } // done RESTARTABLE(VM_ATTACH_CLOSE(this->socket()),rc); delete this; }
// Complete the operation: // - open the pipe to the client // - write the operation result (a jint) // - write the operation output (the result stream) // void Win32AttachOperation::complete(jint result, bufferedStream* result_stream) { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or // java_suspend_self() via check_and_wait_while_suspended() HANDLE hPipe = open_pipe(); if (hPipe != INVALID_HANDLE_VALUE) { BOOL fSuccess; char msg[32]; _snprintf(msg, sizeof(msg), "%d\n", result); msg[sizeof(msg) - 1] = '\0'; fSuccess = write_pipe(hPipe, msg, (int)strlen(msg)); if (fSuccess) { write_pipe(hPipe, (char*) result_stream->base(), (int)(result_stream->size())); } // Need to flush buffers FlushFileBuffers(hPipe); CloseHandle(hPipe); } DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE); if (res == WAIT_OBJECT_0) { // put the operation back on the available list set_next(Win32AttachListener::available()); Win32AttachListener::set_available(this); ::ReleaseMutex(Win32AttachListener::mutex()); } // were we externally suspended while we were waiting? thread->check_and_wait_while_suspended(); }
void NMethodSweeper::sweep_code_cache() { #ifdef ASSERT jlong sweep_start; if (PrintMethodFlushing) { sweep_start = os::javaTimeMillis(); } #endif if (PrintMethodFlushing && Verbose) { tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); } // We want to visit all nmethods after NmethodSweepFraction // invocations so divide the remaining number of nmethods by the // remaining number of invocations. This is only an estimate since // the number of nmethods changes during the sweep so the final // stage must iterate until it there are no more nmethods. int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); assert(!CodeCache_lock->owned_by_self(), "just checking"); { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // The last invocation iterates until there are no more nmethods for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { if (SafepointSynchronize::is_synchronizing()) { // Safepoint request if (PrintMethodFlushing && Verbose) { tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations); } MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); assert(Thread::current()->is_Java_thread(), "should be java thread"); JavaThread* thread = (JavaThread*)Thread::current(); ThreadBlockInVM tbivm(thread); thread->java_suspend_self(); } // Since we will give up the CodeCache_lock, always skip ahead // to the next nmethod. Other blobs can be deleted by other // threads but nmethods are only reclaimed by the sweeper. nmethod* next = CodeCache::next_nmethod(_current); // Now ready to process nmethod and give up CodeCache_lock { MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); process_nmethod(_current); } _seen++; _current = next; } } assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { // we've completed a scan without making progress but there were // nmethods we were unable to process either because they were // locked or were still on stack. We don't have to aggresively // clean them up so just stop scanning. We could scan once more // but that complicates the control logic and it's unlikely to // matter much. if (PrintMethodFlushing) { tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); } } #ifdef ASSERT if(PrintMethodFlushing) { jlong sweep_end = os::javaTimeMillis(); tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start); } #endif if (_invocations == 1) { log_sweep("finished"); } }