< prev index next > src/hotspot/share/prims/jvmtiEnv.cpp
Print this page
#include "runtime/threadSMR.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/vframe.inline.hpp"
#include "runtime/vmThread.hpp"
#include "services/threadService.hpp"
+ #if INCLUDE_TSAN
+ #include "tsan/tsan.hpp"
+ #endif // INCLUDE_TSAN
#include "utilities/exceptions.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/utf8.hpp"
//
// Raw Monitor functions
//
+ // Tsan note: The JVMTI raw monitors are instrumented at JvmtiRawMonitor call
+ // sites instead of inside the JvmtiRawMonitor implementation. This seems
+ // cleaner, and mirrors instrumentation of JVM_RawMonitor* functions.
+
// name - pre-checked for NULL
// monitor_ptr - pre-checked for NULL
jvmtiError
JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);
NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
*monitor_ptr = (jrawMonitorID)rmonitor;
+ TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_CREATE(rmonitor));
+
return JVMTI_ERROR_NONE;
} /* end CreateRawMonitor */
// rmonitor - pre-checked for validity
// failure on systems that don't like destroying synchronization
// objects that are locked.
int r;
int recursion = rmonitor->recursions();
for (int i = 0; i <= recursion; i++) {
+ TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
r = rmonitor->raw_exit(thread);
assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
if (r != JvmtiRawMonitor::M_OK) { // robustness
return JVMTI_ERROR_INTERNAL;
}
// monitor's memory).
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
}
+ TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_DESTROY(rmonitor));
delete rmonitor;
return JVMTI_ERROR_NONE;
} /* end DestroyRawMonitor */
// restore state, still at a safepoint safe state
current_thread->set_thread_state(state);
} else {
rmonitor->raw_enter(thread);
}
+ TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_ACQUIRED(rmonitor));
}
return JVMTI_ERROR_NONE;
} /* end RawMonitorEnter */
// Bool value from exit is false if rmonitor is not in the list.
if (!JvmtiPendingMonitors::exit(rmonitor)) {
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
}
} else {
+ Thread* thread = Thread::current();
TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
int r = rmonitor->raw_exit(thread);
if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
}
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
+ Thread* thread = Thread::current();
+
+ // A wait is modeled in Tsan as a simple release-acquire pair.
+ // The matching release annotation is below.
TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
+ int r = rmonitor->raw_wait(millis, thread);
+ // The matching acquire annotation is above.
TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_ACQUIRED(rmonitor));
switch (r) {
case JvmtiRawMonitor::M_INTERRUPTED:
return JVMTI_ERROR_INTERRUPT;
< prev index next >