test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResumeThreadList/resumethrdlst001/resumethrdlst001.c
changeset 50260 46c67f5e27c2
equal deleted inserted replaced
50259:01d27ae7a84e 50260:46c67f5e27c2
       
     1 /*
       
     2  * Copyright (c) 2003, 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 <string.h>
       
    25 #include "jvmti.h"
       
    26 #include "agent_common.h"
       
    27 #include "jni_tools.h"
       
    28 #include "jvmti_tools.h"
       
    29 
       
    30 #ifdef __cplusplus
       
    31 extern "C" {
       
    32 #endif
       
    33 
       
    34 /* ============================================================================= */
       
    35 
       
    36 /* scaffold objects */
       
    37 static jlong timeout = 0;
       
    38 
       
    39 /* constant names */
       
    40 #define THREAD_NAME     "TestedThread"
       
    41 
       
    42 /* constants */
       
    43 #define DEFAULT_THREADS_COUNT   10
       
    44 
       
    45 static int threadsCount = 0;
       
    46 
       
    47 /* ============================================================================= */
       
    48 
       
    49 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
       
    50                                 const char name[], int foundCount, jthread foundThreads[]);
       
    51 
       
    52 /** Agent algorithm. */
       
    53 static void JNICALL
       
    54 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
       
    55 
       
    56     NSK_DISPLAY0("Wait for threads to start\n");
       
    57     if (!nsk_jvmti_waitForSync(timeout))
       
    58         return;
       
    59 
       
    60     /* perform testing */
       
    61     {
       
    62         jthread* threads = NULL;
       
    63         jvmtiError* results = NULL;
       
    64         int i;
       
    65 
       
    66         NSK_DISPLAY1("Allocate threads array: %d threads\n", threadsCount);
       
    67         if (!NSK_JVMTI_VERIFY(
       
    68                 NSK_CPP_STUB3(Allocate, jvmti, (threadsCount * sizeof(jthread)),
       
    69                                                 (unsigned char**)&threads))) {
       
    70             nsk_jvmti_setFailStatus();
       
    71             return;
       
    72         }
       
    73         NSK_DISPLAY1("  ... allocated array: %p\n", (void*)threads);
       
    74 
       
    75         NSK_DISPLAY1("Allocate results array: %d threads\n", threadsCount);
       
    76         if (!NSK_JVMTI_VERIFY(
       
    77                 NSK_CPP_STUB3(Allocate, jvmti, (threadsCount * sizeof(jvmtiError)),
       
    78                                                 (unsigned char**)&results))) {
       
    79             nsk_jvmti_setFailStatus();
       
    80             return;
       
    81         }
       
    82         NSK_DISPLAY1("  ... allocated array: %p\n", (void*)threads);
       
    83 
       
    84         NSK_DISPLAY1("Find threads: %d threads\n", threadsCount);
       
    85         if (!NSK_VERIFY(fillThreadsByName(jvmti, jni, THREAD_NAME, threadsCount, threads)))
       
    86             return;
       
    87 
       
    88         NSK_DISPLAY0("Suspend threads list\n");
       
    89         if (!NSK_JVMTI_VERIFY(
       
    90                 NSK_CPP_STUB4(SuspendThreadList, jvmti, threadsCount, threads, results))) {
       
    91             nsk_jvmti_setFailStatus();
       
    92             return;
       
    93         }
       
    94 
       
    95         NSK_DISPLAY0("Check threads results:\n");
       
    96         for (i = 0; i < threadsCount; i++) {
       
    97             NSK_DISPLAY3("  ... thread #%d: %s (%d)\n",
       
    98                                 i, TranslateError(results[i]), (int)results[i]);
       
    99             if (!NSK_JVMTI_VERIFY(results[i]))
       
   100                 nsk_jvmti_setFailStatus();
       
   101         }
       
   102 
       
   103         NSK_DISPLAY0("Resume threads list\n");
       
   104         if (!NSK_JVMTI_VERIFY(
       
   105                 NSK_CPP_STUB4(ResumeThreadList, jvmti, threadsCount, threads, results))) {
       
   106             nsk_jvmti_setFailStatus();
       
   107             return;
       
   108         }
       
   109 
       
   110         NSK_DISPLAY0("Check threads results:\n");
       
   111         for (i = 0; i < threadsCount; i++) {
       
   112             NSK_DISPLAY3("  ... thread #%d: %s (%d)\n",
       
   113                                 i, TranslateError(results[i]), (int)results[i]);
       
   114             if (!NSK_JVMTI_VERIFY(results[i]))
       
   115                 nsk_jvmti_setFailStatus();
       
   116         }
       
   117 
       
   118         NSK_DISPLAY0("Get state vector for each thread\n");
       
   119         for (i = 0; i < threadsCount; i++) {
       
   120             jint state = 0;
       
   121 
       
   122             NSK_DISPLAY2("  thread #%d (%p):\n", i, (void*)threads[i]);
       
   123             if (!NSK_JVMTI_VERIFY(
       
   124                     NSK_CPP_STUB3(GetThreadState, jvmti, threads[i], &state))) {
       
   125                 nsk_jvmti_setFailStatus();
       
   126             }
       
   127             NSK_DISPLAY2("  ... got state vector: %s (%d)\n",
       
   128                             TranslateState(state), (int)state);
       
   129 
       
   130             if ((state & JVMTI_THREAD_STATE_SUSPENDED) != 0) {
       
   131                 NSK_COMPLAIN3("ResumeThreadList() does not turn off flag SUSPENDED for thread #%i:\n"
       
   132                               "#   state:  %s (%d)\n",
       
   133                                 i, TranslateState(state), (int)state);
       
   134                 nsk_jvmti_setFailStatus();
       
   135             }
       
   136         }
       
   137 
       
   138         NSK_DISPLAY0("Let threads to run and finish\n");
       
   139         if (!nsk_jvmti_resumeSync())
       
   140             return;
       
   141 
       
   142         NSK_DISPLAY0("Wait for thread to finish\n");
       
   143         if (!nsk_jvmti_waitForSync(timeout))
       
   144             return;
       
   145 
       
   146         NSK_DISPLAY0("Delete threads references\n");
       
   147         for (i = 0; i < threadsCount; i++) {
       
   148             if (threads[i] != NULL)
       
   149                 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threads[i]));
       
   150         }
       
   151 
       
   152         NSK_DISPLAY1("Deallocate threads array: %p\n", (void*)threads);
       
   153         if (!NSK_JVMTI_VERIFY(
       
   154                 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads))) {
       
   155             nsk_jvmti_setFailStatus();
       
   156         }
       
   157 
       
   158         NSK_DISPLAY1("Deallocate results array: %p\n", (void*)results);
       
   159         if (!NSK_JVMTI_VERIFY(
       
   160                 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)results))) {
       
   161             nsk_jvmti_setFailStatus();
       
   162         }
       
   163     }
       
   164 
       
   165     NSK_DISPLAY0("Let debugee to finish\n");
       
   166     if (!nsk_jvmti_resumeSync())
       
   167         return;
       
   168 }
       
   169 
       
   170 /* ============================================================================= */
       
   171 
       
   172 /** Find threads whose name starts with specified name prefix. */
       
   173 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
       
   174                             const char name[], int foundCount, jthread foundThreads[]) {
       
   175     jint count = 0;
       
   176     jthread* threads = NULL;
       
   177 
       
   178     size_t len = strlen(name);
       
   179     int found = 0;
       
   180     int i;
       
   181 
       
   182     for (i = 0; i < foundCount; i++) {
       
   183         foundThreads[i] = NULL;
       
   184     }
       
   185 
       
   186     if (!NSK_JVMTI_VERIFY(
       
   187             NSK_CPP_STUB3(GetAllThreads, jvmti, &count, &threads))) {
       
   188         nsk_jvmti_setFailStatus();
       
   189         return NSK_FALSE;
       
   190     }
       
   191 
       
   192     found = 0;
       
   193     for (i = 0; i < count; i++) {
       
   194         jvmtiThreadInfo info;
       
   195 
       
   196         if (!NSK_JVMTI_VERIFY(
       
   197                 NSK_CPP_STUB3(GetThreadInfo, jvmti, threads[i], &info))) {
       
   198             nsk_jvmti_setFailStatus();
       
   199             break;
       
   200         }
       
   201 
       
   202         if (info.name != NULL && strncmp(name, info.name, len) == 0) {
       
   203             NSK_DISPLAY3("  ... found thread #%d: %p (%s)\n",
       
   204                                     found, threads[i], info.name);
       
   205             if (found < foundCount)
       
   206                 foundThreads[found] = threads[i];
       
   207             found++;
       
   208         }
       
   209 
       
   210     }
       
   211 
       
   212     if (!NSK_JVMTI_VERIFY(
       
   213                 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads))) {
       
   214         nsk_jvmti_setFailStatus();
       
   215         return NSK_FALSE;
       
   216     }
       
   217 
       
   218     if (found != foundCount) {
       
   219         NSK_COMPLAIN3("Unexpected number of tested threads found:\n"
       
   220                       "#   name:     %s\n"
       
   221                       "#   found:    %d\n"
       
   222                       "#   expected: %d\n",
       
   223                       name, found, foundCount);
       
   224         nsk_jvmti_setFailStatus();
       
   225         return NSK_FALSE;
       
   226     }
       
   227 
       
   228     NSK_DISPLAY1("Make global references for threads: %d threads\n", foundCount);
       
   229     for (i = 0; i < foundCount; i++) {
       
   230         if (!NSK_JNI_VERIFY(jni, (foundThreads[i] = (jthread)
       
   231                     NSK_CPP_STUB2(NewGlobalRef, jni, foundThreads[i])) != NULL)) {
       
   232             nsk_jvmti_setFailStatus();
       
   233             return NSK_FALSE;
       
   234         }
       
   235         NSK_DISPLAY2("  ... thread #%d: %p\n", i, foundThreads[i]);
       
   236     }
       
   237 
       
   238     return NSK_TRUE;
       
   239 }
       
   240 
       
   241 /* ============================================================================= */
       
   242 
       
   243 /** Agent library initialization. */
       
   244 #ifdef STATIC_BUILD
       
   245 JNIEXPORT jint JNICALL Agent_OnLoad_resumethrdlst001(JavaVM *jvm, char *options, void *reserved) {
       
   246     return Agent_Initialize(jvm, options, reserved);
       
   247 }
       
   248 JNIEXPORT jint JNICALL Agent_OnAttach_resumethrdlst001(JavaVM *jvm, char *options, void *reserved) {
       
   249     return Agent_Initialize(jvm, options, reserved);
       
   250 }
       
   251 JNIEXPORT jint JNI_OnLoad_resumethrdlst001(JavaVM *jvm, char *options, void *reserved) {
       
   252     return JNI_VERSION_1_8;
       
   253 }
       
   254 #endif
       
   255 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
       
   256     jvmtiEnv* jvmti = NULL;
       
   257 
       
   258     /* init framework and parse options */
       
   259     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
       
   260         return JNI_ERR;
       
   261 
       
   262     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
       
   263 
       
   264     /* get options */
       
   265     threadsCount = nsk_jvmti_findOptionIntValue("threads", DEFAULT_THREADS_COUNT);
       
   266     if (!NSK_VERIFY(threadsCount > 0))
       
   267         return JNI_ERR;
       
   268 
       
   269     /* create JVMTI environment */
       
   270     if (!NSK_VERIFY((jvmti =
       
   271             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
       
   272         return JNI_ERR;
       
   273 
       
   274     /* add specific capabilities for suspending thread */
       
   275     {
       
   276         jvmtiCapabilities suspendCaps;
       
   277         memset(&suspendCaps, 0, sizeof(suspendCaps));
       
   278         suspendCaps.can_suspend = 1;
       
   279         if (!NSK_JVMTI_VERIFY(
       
   280                 NSK_CPP_STUB2(AddCapabilities, jvmti, &suspendCaps)))
       
   281             return JNI_ERR;
       
   282     }
       
   283 
       
   284     /* register agent proc and arg */
       
   285     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
       
   286         return JNI_ERR;
       
   287 
       
   288     return JNI_OK;
       
   289 }
       
   290 
       
   291 /* ============================================================================= */
       
   292 
       
   293 #ifdef __cplusplus
       
   294 }
       
   295 #endif