< prev index next >

src/hotspot/share/prims/jvmtiEnv.cpp

Print this page
*** 71,10 ***
--- 71,13 ---
  #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"
  
  

*** 3224,19 ***
--- 3227,25 ---
  
    //
    // 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

*** 3255,10 ***
--- 3264,11 ---
        // 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;
          }

*** 3273,10 ***
--- 3283,11 ---
        // 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 */
  

*** 3316,10 ***
--- 3327,11 ---
        // 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 */
  
  

*** 3333,10 ***
--- 3345,11 ---
      // 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;
      }

*** 3346,11 ***
--- 3359,17 ---
  
  
  // 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 >