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 <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <jvmti.h> 28 #include "agent_common.h" 29 30 #include "nsk_tools.h" 31 #include "JVMTITools.h" 32 #include "jvmti_tools.h" 33 34 extern "C" { 35 36 #define STATUS_FAILED 2 37 #define PASSED 0 38 39 #define MEM_SIZE 1024 40 41 static jvmtiEnv *jvmti = NULL; 42 static jvmtiEventCallbacks callbacks; 43 static jvmtiCapabilities caps; 44 45 static volatile jint result = PASSED; 46 static volatile int gcstart = 0; 47 unsigned char *mem; 48 49 static void rawMonitorFunc(jvmtiEnv *jvmti_env, const char *msg) { 50 jrawMonitorID _lock; 51 52 NSK_DISPLAY1("%s: creating a raw monitor ...\n", 53 msg); 54 if (!NSK_JVMTI_VERIFY(jvmti_env->CreateRawMonitor("_lock", &_lock))) { 55 result = STATUS_FAILED; 56 NSK_COMPLAIN1("TEST FAILED: %s: unable to create a raw monitor\n\n", 57 msg); 58 return; 59 } 60 NSK_DISPLAY1("CHECK PASSED: %s: raw monitor created\n", 61 msg); 62 63 NSK_DISPLAY1("%s: entering the raw monitor ...\n", 64 msg); 65 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(_lock))) { 66 result = STATUS_FAILED; 67 NSK_COMPLAIN1("TEST FAILED: %s: unable to enter the raw monitor\n\n", 68 msg); 69 } 70 else { 71 NSK_DISPLAY1("CHECK PASSED: %s: the raw monitor entered\n", 72 msg); 73 74 NSK_DISPLAY1("%s: waiting the raw monitor ...\n", 75 msg); 76 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorWait(_lock, (jlong)10))) { 77 result = STATUS_FAILED; 78 NSK_COMPLAIN1("TEST FAILED: %s: unable to wait the raw monitor\n\n", 79 msg); 80 } 81 NSK_DISPLAY1("CHECK PASSED: %s: the raw monitor waited\n", 82 msg); 83 84 85 NSK_DISPLAY1("%s: notifying a single thread waiting on the raw monitor ...\n", 86 msg); 87 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorNotify(_lock))) { 88 result = STATUS_FAILED; 89 NSK_COMPLAIN1("TEST FAILED: %s: unable to notify single thread\n\n", 90 msg); 91 } 92 NSK_DISPLAY1("CHECK PASSED: %s: single thread notified\n", 93 msg); 94 95 96 NSK_DISPLAY1("%s: notifying all threads waiting on the raw monitor ...\n", 97 msg); 98 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorNotifyAll(_lock))) { 99 result = STATUS_FAILED; 100 NSK_COMPLAIN1("TEST FAILED: %s: unable to notify all threads\n\n", 101 msg); 102 } 103 NSK_DISPLAY1("CHECK PASSED: %s: all threads notified\n", 104 msg); 105 106 107 NSK_DISPLAY1("%s: exiting the raw monitor ...\n", 108 msg); 109 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(_lock))) { 110 result = STATUS_FAILED; 111 NSK_COMPLAIN1("TEST FAILED: %s: unable to exit the raw monitor\n\n", 112 msg); 113 } 114 NSK_DISPLAY1("CHECK PASSED: %s: the raw monitor exited\n", 115 msg); 116 } 117 118 NSK_DISPLAY1("%s: destroying the raw monitor ...\n", 119 msg); 120 if (!NSK_JVMTI_VERIFY(jvmti_env->DestroyRawMonitor(_lock))) { 121 result = STATUS_FAILED; 122 NSK_COMPLAIN1("TEST FAILED: %s: unable to destroy a raw monitor\n", 123 msg); 124 return; 125 } 126 NSK_DISPLAY1("CHECK PASSED: %s: the raw monitor destroyed\n", 127 msg); 128 } 129 130 static void memoryFunc(jvmtiEnv *jvmti_env, const char *msg) { 131 NSK_DISPLAY1("%s: allocating memory ...\n", 132 msg); 133 if (!NSK_JVMTI_VERIFY(jvmti_env->Allocate(MEM_SIZE, &mem))) { 134 result = STATUS_FAILED; 135 NSK_COMPLAIN1("TEST FAILED: %s: unable to allocate memory\n\n", 136 msg); 137 return; 138 } 139 else 140 NSK_DISPLAY1("CHECK PASSED: %s: memory has been allocated successfully\n", 141 msg); 142 143 NSK_DISPLAY1("%s: deallocating memory ...\n", 144 msg); 145 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate(mem))) { 146 result = STATUS_FAILED; 147 NSK_COMPLAIN1("TEST FAILED: %s: unable to deallocate memory\n\n", 148 msg); 149 } 150 else 151 NSK_DISPLAY1("CHECK PASSED: %s: memory has been deallocated successfully\n\n", 152 msg); 153 } 154 155 /** callback functions **/ 156 void JNICALL 157 GarbageCollectionFinish(jvmtiEnv *jvmti_env) { 158 gcstart++; 159 NSK_DISPLAY1(">>>> GarbageCollectionFinish event #%d received\n", 160 gcstart); 161 162 rawMonitorFunc(jvmti_env, "GarbageCollectionFinish"); 163 164 memoryFunc(jvmti_env, "GarbageCollectionFinish"); 165 166 NSK_DISPLAY0("<<<<\n\n"); 167 } 168 169 void JNICALL 170 VMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) { 171 NSK_DISPLAY0("VMDeath event received\n"); 172 173 if (result == STATUS_FAILED) 174 exit(95 + STATUS_FAILED); 175 } 176 177 /************************/ 178 179 #ifdef STATIC_BUILD 180 JNIEXPORT jint JNICALL Agent_OnLoad_gcfinish001(JavaVM *jvm, char *options, void *reserved) { 181 return Agent_Initialize(jvm, options, reserved); 182 } 183 JNIEXPORT jint JNICALL Agent_OnAttach_gcfinish001(JavaVM *jvm, char *options, void *reserved) { 184 return Agent_Initialize(jvm, options, reserved); 185 } 186 JNIEXPORT jint JNI_OnLoad_gcfinish001(JavaVM *jvm, char *options, void *reserved) { 187 return JNI_VERSION_1_8; 188 } 189 #endif 190 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 191 /* init framework and parse options */ 192 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 193 return JNI_ERR; 194 195 /* create JVMTI environment */ 196 if (!NSK_VERIFY((jvmti = 197 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 198 return JNI_ERR; 199 200 /* add capability to generate compiled method events */ 201 memset(&caps, 0, sizeof(jvmtiCapabilities)); 202 caps.can_generate_garbage_collection_events = 1; 203 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 204 return JNI_ERR; 205 206 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 207 return JNI_ERR; 208 209 if (!caps.can_generate_garbage_collection_events) 210 NSK_DISPLAY0("Warning: generation of garbage collection events is not implemented\n"); 211 212 /* set event callback */ 213 NSK_DISPLAY0("setting event callbacks ...\n"); 214 (void) memset(&callbacks, 0, sizeof(callbacks)); 215 callbacks.VMDeath = &VMDeath; 216 callbacks.GarbageCollectionFinish = &GarbageCollectionFinish; 217 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) 218 return JNI_ERR; 219 220 NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n"); 221 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL))) 222 return JNI_ERR; 223 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL))) 224 return JNI_ERR; 225 NSK_DISPLAY0("enabling the events done\n\n"); 226 227 return JNI_OK; 228 } 229 230 }