test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC05/tc05t001/tc05t001.cpp
changeset 51551 e409244ce72e
parent 50260 46c67f5e27c2
child 51774 79dc492c00ab
equal deleted inserted replaced
51550:a2f1923b3e16 51551:e409244ce72e
       
     1 /*
       
     2  * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #include <stdlib.h>
       
    25 #include <string.h>
       
    26 #include "jni_tools.h"
       
    27 #include "agent_common.h"
       
    28 #include "jvmti_tools.h"
       
    29 
       
    30 #ifdef __cplusplus
       
    31 extern "C" {
       
    32 #endif
       
    33 
       
    34 /* ========================================================================== */
       
    35 
       
    36 static const jlong EXPECTED_TIMEOUT = 1;
       
    37 /*
       
    38  * The expected timeout accuracy was already increased from 100000 to 300000.
       
    39  * Please, do not increase it anymore if the test still fails with the message:
       
    40  *  "(waitedTime - waitTime) >= (EXPECTED_TIMEOUT * 1000000) - EXPECTED_TIMEOUT_ACCURACY_NS"
       
    41  */
       
    42 static const jlong EXPECTED_TIMEOUT_ACCURACY_NS = 300000;
       
    43 
       
    44 static const jlong EXPECTED_ACCURACY = 10;
       
    45 
       
    46 /* scaffold objects */
       
    47 static jlong timeout = 0;
       
    48 
       
    49 /* test objects */
       
    50 static jthread thread = NULL;
       
    51 static jobject object_M = NULL;
       
    52 static volatile int waitEventsCount = 0;
       
    53 static volatile int waitedEventsCount = 0;
       
    54 static jlong waitTime = 0;
       
    55 static jlong waitThreadCpuTime = 0;
       
    56 static jlong waitedTime = 0;
       
    57 static jlong waitedThreadCpuTime = 0;
       
    58 
       
    59 /* ========================================================================== */
       
    60 
       
    61 void JNICALL
       
    62 MonitorWait(jvmtiEnv *jvmti, JNIEnv* jni,
       
    63         jthread thr, jobject obj, jlong tout) {
       
    64     char buffer[32];
       
    65 
       
    66     if (!NSK_VERIFY(thr != NULL)) {
       
    67         nsk_jvmti_setFailStatus();
       
    68         return;
       
    69     }
       
    70 
       
    71     if (!NSK_VERIFY(obj != NULL)) {
       
    72         nsk_jvmti_setFailStatus();
       
    73         return;
       
    74     }
       
    75 
       
    76     /* check if event is for tested thread and object */
       
    77     if (NSK_CPP_STUB3(IsSameObject, jni, thread, thr) &&
       
    78             NSK_CPP_STUB3(IsSameObject, jni, object_M, obj)) {
       
    79         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(
       
    80                 GetThreadCpuTime, jvmti, thr, &waitThreadCpuTime))) {
       
    81             nsk_jvmti_setFailStatus();
       
    82         }
       
    83         if (!NSK_JVMTI_VERIFY(
       
    84                 NSK_CPP_STUB2(GetTime, jvmti, &waitTime))) {
       
    85             nsk_jvmti_setFailStatus();
       
    86         }
       
    87         waitEventsCount++;
       
    88         NSK_DISPLAY0("MonitorWait event:\n");
       
    89         NSK_DISPLAY3("\tthread: %p, object: %p, timeout: %s\n",
       
    90             thr, obj, jlong_to_string(tout, buffer));
       
    91         NSK_DISPLAY1("\ttime: %s\n",
       
    92             jlong_to_string(waitTime, buffer));
       
    93         NSK_DISPLAY1("\tthread CPU time: %s\n",
       
    94             jlong_to_string(waitThreadCpuTime, buffer));
       
    95 
       
    96         if (!NSK_VERIFY(tout == EXPECTED_TIMEOUT)) {
       
    97             nsk_jvmti_setFailStatus();
       
    98         }
       
    99     }
       
   100 }
       
   101 
       
   102 void JNICALL
       
   103 MonitorWaited(jvmtiEnv *jvmti, JNIEnv* jni,
       
   104         jthread thr, jobject obj, jboolean timed_out) {
       
   105     char buffer[32];
       
   106 
       
   107     if (!NSK_VERIFY(thr != NULL)) {
       
   108         nsk_jvmti_setFailStatus();
       
   109         return;
       
   110     }
       
   111 
       
   112     if (!NSK_VERIFY(obj != NULL)) {
       
   113         nsk_jvmti_setFailStatus();
       
   114         return;
       
   115     }
       
   116 
       
   117     /* check if event is for tested thread and object */
       
   118     if (NSK_CPP_STUB3(IsSameObject, jni, thread, thr) &&
       
   119             NSK_CPP_STUB3(IsSameObject, jni, object_M, obj)) {
       
   120         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(
       
   121                 GetThreadCpuTime, jvmti, thr, &waitedThreadCpuTime))) {
       
   122             nsk_jvmti_setFailStatus();
       
   123         }
       
   124         if (!NSK_JVMTI_VERIFY(
       
   125                 NSK_CPP_STUB2(GetTime, jvmti, &waitedTime))) {
       
   126             nsk_jvmti_setFailStatus();
       
   127         }
       
   128         waitedEventsCount++;
       
   129         NSK_DISPLAY0("MonitorWaited event:\n");
       
   130         NSK_DISPLAY3("\tthread: %p, object: %p, timed_out: %s\n",
       
   131             thr, obj, (timed_out==JNI_TRUE) ? "true" : "false");
       
   132         NSK_DISPLAY1("\tGetTime: %s\n",
       
   133             jlong_to_string(waitedTime, buffer));
       
   134         NSK_DISPLAY1("\tthread CPU time: %s\n",
       
   135             jlong_to_string(waitedThreadCpuTime, buffer));
       
   136     }
       
   137 }
       
   138 
       
   139 /* ========================================================================== */
       
   140 
       
   141 static int prepare(jvmtiEnv* jvmti, JNIEnv* jni) {
       
   142     const char* THREAD_NAME = "Debuggee Thread";
       
   143     const char* FIELD_SIG = "Ljava/lang/Object;";
       
   144     jvmtiThreadInfo info;
       
   145     jthread *threads = NULL;
       
   146     jint threads_count = 0;
       
   147     jfieldID field = NULL;
       
   148     jclass klass = NULL;
       
   149     int i;
       
   150 
       
   151     NSK_DISPLAY0("Prepare: find tested thread\n");
       
   152 
       
   153     /* get all live threads */
       
   154     if (!NSK_JVMTI_VERIFY(
       
   155            NSK_CPP_STUB3(GetAllThreads, jvmti, &threads_count, &threads)))
       
   156         return NSK_FALSE;
       
   157 
       
   158     if (!NSK_VERIFY(threads_count > 0 && threads != NULL))
       
   159         return NSK_FALSE;
       
   160 
       
   161     /* find tested thread */
       
   162     for (i = 0; i < threads_count; i++) {
       
   163         if (!NSK_VERIFY(threads[i] != NULL))
       
   164             return NSK_FALSE;
       
   165 
       
   166         /* get thread information */
       
   167         if (!NSK_JVMTI_VERIFY(
       
   168                 NSK_CPP_STUB3(GetThreadInfo, jvmti, threads[i], &info)))
       
   169             return NSK_FALSE;
       
   170 
       
   171         NSK_DISPLAY3("    thread #%d (%s): %p\n", i, info.name, threads[i]);
       
   172 
       
   173         /* find by name */
       
   174         if (info.name != NULL && (strcmp(info.name, THREAD_NAME) == 0)) {
       
   175             thread = threads[i];
       
   176         }
       
   177 
       
   178         if (info.name != NULL) {
       
   179             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(
       
   180                     Deallocate, jvmti, (unsigned char*)info.name)))
       
   181                 return NSK_FALSE;
       
   182         }
       
   183     }
       
   184 
       
   185     /* deallocate threads list */
       
   186     if (!NSK_JVMTI_VERIFY(
       
   187             NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads)))
       
   188         return NSK_FALSE;
       
   189 
       
   190     if (thread == NULL) {
       
   191         NSK_COMPLAIN0("Debuggee thread not found");
       
   192         return NSK_FALSE;
       
   193     }
       
   194 
       
   195     /* make thread accessable for a long time */
       
   196     if (!NSK_JNI_VERIFY(jni, (thread =
       
   197             NSK_CPP_STUB2(NewGlobalRef, jni, thread)) != NULL))
       
   198         return NSK_FALSE;
       
   199 
       
   200     /* get tested thread class */
       
   201     if (!NSK_JNI_VERIFY(jni, (klass =
       
   202             NSK_CPP_STUB2(GetObjectClass, jni, thread)) != NULL))
       
   203         return NSK_FALSE;
       
   204 
       
   205     /* get tested thread field 'M' */
       
   206     if (!NSK_JNI_VERIFY(jni, (field =
       
   207             NSK_CPP_STUB4(GetFieldID, jni, klass, "M", FIELD_SIG)) != NULL))
       
   208         return NSK_FALSE;
       
   209 
       
   210     if (!NSK_JNI_VERIFY(jni, (object_M =
       
   211             NSK_CPP_STUB3(GetObjectField, jni, thread, field)) != NULL))
       
   212         return NSK_FALSE;
       
   213 
       
   214     /* make object accessable for a long time */
       
   215     if (!NSK_JNI_VERIFY(jni, (object_M =
       
   216             NSK_CPP_STUB2(NewGlobalRef, jni, object_M)) != NULL))
       
   217         return NSK_FALSE;
       
   218 
       
   219     /* enable MonitorWait event */
       
   220     if (!NSK_JVMTI_VERIFY(
       
   221             NSK_CPP_STUB4(SetEventNotificationMode, jvmti, JVMTI_ENABLE,
       
   222                 JVMTI_EVENT_MONITOR_WAIT, NULL)))
       
   223         return NSK_FALSE;
       
   224 
       
   225     /* enable MonitorWaited event */
       
   226     if (!NSK_JVMTI_VERIFY(
       
   227             NSK_CPP_STUB4(SetEventNotificationMode, jvmti, JVMTI_ENABLE,
       
   228                 JVMTI_EVENT_MONITOR_WAITED, NULL)))
       
   229         return NSK_FALSE;
       
   230 
       
   231     return NSK_TRUE;
       
   232 }
       
   233 
       
   234 static int clean(jvmtiEnv* jvmti, JNIEnv* jni) {
       
   235 
       
   236     /* disable MonitorWait event */
       
   237     if (!NSK_JVMTI_VERIFY(
       
   238             NSK_CPP_STUB4(SetEventNotificationMode, jvmti, JVMTI_DISABLE,
       
   239                 JVMTI_EVENT_MONITOR_WAIT, NULL)))
       
   240         nsk_jvmti_setFailStatus();
       
   241 
       
   242     /* disable MonitorWaited event */
       
   243     if (!NSK_JVMTI_VERIFY(
       
   244             NSK_CPP_STUB4(SetEventNotificationMode, jvmti, JVMTI_DISABLE,
       
   245                 JVMTI_EVENT_MONITOR_WAITED, NULL)))
       
   246         nsk_jvmti_setFailStatus();
       
   247 
       
   248     return NSK_TRUE;
       
   249 }
       
   250 
       
   251 /* ========================================================================== */
       
   252 
       
   253 /* agent algorithm */
       
   254 static void JNICALL
       
   255 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
       
   256     char buffer[32];
       
   257 
       
   258     /* wait for initial sync */
       
   259     if (!nsk_jvmti_waitForSync(timeout))
       
   260         return;
       
   261 
       
   262     if (!prepare(jvmti, jni)) {
       
   263         nsk_jvmti_setFailStatus();
       
   264         return;
       
   265     }
       
   266 
       
   267     /* resume debugee to catch MonitorContendedEntered events */
       
   268     if (!(NSK_VERIFY(nsk_jvmti_resumeSync()) &&
       
   269           NSK_VERIFY(nsk_jvmti_waitForSync(timeout))))
       
   270         return;
       
   271 
       
   272     NSK_DISPLAY1("Number of MonitorWait events: %d\n", waitEventsCount);
       
   273     if (!(NSK_VERIFY(waitEventsCount == 1))) {
       
   274         nsk_jvmti_setFailStatus();
       
   275     }
       
   276 
       
   277     NSK_DISPLAY1("Number of MonitorWaited events: %d\n", waitedEventsCount);
       
   278     if (!(NSK_VERIFY(waitedEventsCount == 1))) {
       
   279         nsk_jvmti_setFailStatus();
       
   280     }
       
   281 
       
   282     NSK_DISPLAY1("Time frame between the events: %s ns\n",
       
   283         jlong_to_string(waitedTime - waitTime, buffer));
       
   284     if (!(NSK_VERIFY((waitedTime - waitTime) >= (EXPECTED_TIMEOUT * 1000000) - EXPECTED_TIMEOUT_ACCURACY_NS))) {
       
   285 #if (defined(WIN32) || defined(_WIN32))
       
   286         /* Do not fail on Windows as spurious wakeups are expected. The JDK-6313903 was closed as "Won't Fix". */
       
   287 #else
       
   288         nsk_jvmti_setFailStatus();
       
   289 #endif
       
   290         printf("waitedTime: %" LL "d,  waitTime: %" LL "d, waitedTime - waitTime: %" LL "d\n",
       
   291                 waitedTime, waitTime, waitedTime - waitTime);
       
   292     }
       
   293 
       
   294     NSK_DISPLAY1("Thread CPU time between the events: %s ns\n",
       
   295         jlong_to_string(waitedThreadCpuTime - waitThreadCpuTime, buffer));
       
   296     if (!(NSK_VERIFY((waitedThreadCpuTime - waitThreadCpuTime)
       
   297             < (EXPECTED_ACCURACY * 1000000)))) {
       
   298         nsk_jvmti_setFailStatus();
       
   299         printf("waitedThreadCpuTime: %" LL "d, waitThreadCpuTime: %" LL "d, waitedThreadCpuTime - waitThreadCpuTime: %" LL "d\n",
       
   300                 waitedThreadCpuTime, waitThreadCpuTime, waitedThreadCpuTime - waitThreadCpuTime);
       
   301     }
       
   302 
       
   303     if (!clean(jvmti, jni)) {
       
   304         nsk_jvmti_setFailStatus();
       
   305         return;
       
   306     }
       
   307 
       
   308     /* resume debugee after last sync */
       
   309     if (!nsk_jvmti_resumeSync())
       
   310         return;
       
   311 }
       
   312 
       
   313 /* ========================================================================== */
       
   314 
       
   315 /* agent library initialization */
       
   316 #ifdef STATIC_BUILD
       
   317 JNIEXPORT jint JNICALL Agent_OnLoad_tc05t001(JavaVM *jvm, char *options, void *reserved) {
       
   318     return Agent_Initialize(jvm, options, reserved);
       
   319 }
       
   320 JNIEXPORT jint JNICALL Agent_OnAttach_tc05t001(JavaVM *jvm, char *options, void *reserved) {
       
   321     return Agent_Initialize(jvm, options, reserved);
       
   322 }
       
   323 JNIEXPORT jint JNI_OnLoad_tc05t001(JavaVM *jvm, char *options, void *reserved) {
       
   324     return JNI_VERSION_1_8;
       
   325 }
       
   326 #endif
       
   327 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
       
   328     jvmtiEnv* jvmti = NULL;
       
   329     jvmtiCapabilities caps;
       
   330     jvmtiEventCallbacks callbacks;
       
   331 
       
   332     /* init framework and parse options */
       
   333     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
       
   334         return JNI_ERR;
       
   335 
       
   336     timeout = nsk_jvmti_getWaitTime() * 60000;
       
   337     NSK_DISPLAY1("Timeout: %d msc\n", (int)timeout);
       
   338 
       
   339     /* create JVMTI environment */
       
   340     if (!NSK_VERIFY((jvmti =
       
   341             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
       
   342         return JNI_ERR;
       
   343 
       
   344     /* add capabilities */
       
   345     memset(&caps, 0, sizeof(caps));
       
   346     caps.can_generate_monitor_events = 1;
       
   347     caps.can_get_thread_cpu_time = 1;
       
   348     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps)))
       
   349         return JNI_ERR;
       
   350 
       
   351     memset(&callbacks, 0, sizeof(callbacks));
       
   352     callbacks.MonitorWait = &MonitorWait;
       
   353     callbacks.MonitorWaited = &MonitorWaited;
       
   354     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks, jvmti,
       
   355             &callbacks, sizeof(callbacks))))
       
   356         return JNI_ERR;
       
   357 
       
   358     /* register agent proc and arg */
       
   359     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
       
   360         return JNI_ERR;
       
   361 
       
   362     return JNI_OK;
       
   363 }
       
   364 
       
   365 /* ========================================================================== */
       
   366 
       
   367 #ifdef __cplusplus
       
   368 }
       
   369 #endif