Skip to content
Permalink
Browse files
add more use of lib get_thread_name in a couple jvmti/vthread tests
  • Loading branch information
sspitsyn committed Mar 5, 2021
1 parent a86a1a1 commit 0deb93b4f3fcb18b265eda9fc0a1f8f6455a9aab
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 87 deletions.
@@ -157,10 +157,10 @@ test_thread_suspend_list(JNIEnv* jni, const jthread* thread_list) {

for (int idx = 0; idx < VTHREAD_CNT; idx++) {
jthread thread = thread_list[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_thread_suspend_list: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

check_suspended_state(jni, thread, idx, info.name,"SuspendThreadList");
check_suspended_state(jni, thread, idx, tname,"SuspendThreadList");
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_thread_suspend_list finished\n"); fflush(0);
}
@@ -177,10 +177,10 @@ test_thread_resume_list(JNIEnv* jni, const jthread* thread_list) {

for (int idx = 0; idx < VTHREAD_CNT; idx++) {
jthread thread = thread_list[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_thread_resume_list: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

check_resumed_state(jni, thread, idx, info.name, "ResumeThreadList");
check_resumed_state(jni, thread, idx, tname, "ResumeThreadList");
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_thread_resume_list: finished\n"); fflush(0);
}
@@ -202,19 +202,19 @@ test_vthread_suspend_all(JNIEnv* jni, const jthread* thread_list, int suspend_ma

for (int idx = 0; idx < VTHREAD_CNT; idx++) {
jthread thread = thread_list[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_vthread_suspend_all: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

if (idx < EXCLUDE_CNT && ((1 << idx) & suspend_mask) == 0) {
// thread is in exclude list and initially resumed: expected to remain resumed
check_resumed_state(jni, thread, idx, info.name, "SuspendAllVirtualThreads");
check_resumed_state(jni, thread, idx, tname, "SuspendAllVirtualThreads");

err = jvmti->SuspendThread(thread);
check_jvmti_status(jni, err, "test_vthread_suspend_all: error in JVMTI SuspendThread");
} else {
// thread is not in exclude list or was initially suspended: expected to be suspended
check_suspended_state(jni, thread, idx, info.name, "SuspendAllVirtualThreads");
check_suspended_state(jni, thread, idx, tname, "SuspendAllVirtualThreads");
}
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_vthread_suspend_all finished\n"); fflush(0);
}
@@ -236,19 +236,19 @@ test_vthread_resume_all(JNIEnv* jni, const jthread* thread_list, int suspend_mas

for (int idx = 0; idx < VTHREAD_CNT; idx++) {
jthread thread = thread_list[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_vthread_resume_all: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

if (idx < EXCLUDE_CNT && ((1 << idx) & suspend_mask) != 0) {
// thread is in exclude list and suspended: expected to remain suspended
check_suspended_state(jni, thread, idx, info.name, "ResumeAllVirtualThreads");
check_suspended_state(jni, thread, idx, tname, "ResumeAllVirtualThreads");

err = jvmti->ResumeThread(thread); // is expected to be resumed later
check_jvmti_status(jni, err, "test_vthread_resume_all: error in JVMTI ResumeThread");
} else {
// thread is not in exclude list or was initially resumed: expected to be resumed
check_resumed_state(jni, thread, idx, info.name, "ResumeAllVirtualThreads");
check_resumed_state(jni, thread, idx, tname, "ResumeAllVirtualThreads");
}
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_vthread_resume_all: finished\n"); fflush(0);
}
@@ -264,13 +264,13 @@ test_vthread_suspend_half(JNIEnv* jni, const jthread* thread_list) {
continue; // skip odd indeces
}
jthread thread = thread_list[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_vthread_suspend_half: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

err = jvmti->SuspendThread(thread);
check_jvmti_status(jni, err, "test_vthread_suspend_half: error in JVMTI SuspendThread");

check_suspended_state(jni, thread, idx, info.name, "SuspendThread");
check_suspended_state(jni, thread, idx, tname, "SuspendThread");
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_vthread_suspend_half finished\n"); fflush(0);
}
@@ -286,14 +286,13 @@ test_vthread_resume_half(JNIEnv* jni, const jthread* thread_list) {
continue; // skip odd indeces
}
jthread thread = thread_list[idx];

err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_vthread_resume_half: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

err = jvmti->ResumeThread(thread);
check_jvmti_status(jni, err, "test_vthread_resume_half: error in JVMTI ResumeThread");

check_resumed_state(jni, thread, idx, info.name, "ResumeThread");
check_resumed_state(jni, thread, idx, tname, "ResumeThread");
deallocate(jvmti, jni, (void*)tname);
}
printf("\n## Agent: test_vthread_resume_half: finished\n"); fflush(0);
}
@@ -305,15 +304,14 @@ test_threads_suspend_resume(JNIEnv* jni, jint thread_cnt, jthread* tested_thread

for (int idx = 0; idx < thread_cnt; idx++) {
jthread thread = tested_threads[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "test_threads_suspend_resume: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

printf("\n");
test_thread_suspend(jni, thread, idx, info.name);
test_thread_resume(jni, thread, idx, info.name);
test_thread_suspend(jni, thread, idx, tname);
test_thread_resume(jni, thread, idx, tname);

err = jvmti->Deallocate((unsigned char*)info.name);
check_jvmti_status(jni, err, "test_threads_suspend_resume: error in JVMTI Deallocate");
deallocate(jvmti, jni, (void*)tname);
}
}

@@ -333,6 +331,8 @@ test_jvmti_functions_for_one_thread(JNIEnv* jni, jthread thread) {

// test JVMTI GetStackTrace
test_get_stack_trace(jni, thread);

deallocate(jvmti, jni, (void*)tname);
}

static void
@@ -368,16 +368,14 @@ get_cthreads(JNIEnv* jni, jthread** cthreads_p) {

for (int idx = 0; idx < all_cnt; idx++) {
jthread thread = tested_cthreads[idx];
err = jvmti->GetThreadInfo(thread, &info);
check_jvmti_status(jni, err, "get_cthreads: error in JVMTI GetThreadInfo");
char* tname = get_thread_name(jvmti, jni, thread);

char* tname = info.name;
if (strncmp(tname, CTHREAD_NAME_START, CTHREAD_NAME_START_LEN) != 0) {
continue;
}
tested_cthreads[ct_cnt++] = thread;
err = jvmti->Deallocate((unsigned char*)tname);
check_jvmti_status(jni, err, "get_cthreads: error in JVMTI Deallocate");
deallocate(jvmti, jni, (void*)tname);
}
*cthreads_p = tested_cthreads;
return ct_cnt;
@@ -32,9 +32,7 @@ extern "C" {

typedef struct Tinfo {
jboolean just_scheduled;
jboolean was_run;
jboolean was_yield;
const char* thr_name;
const char* tname;
} Tinfo;

static const int MAX_EVENTS_TO_PROCESS = 20;
@@ -45,18 +43,18 @@ static jboolean continuation_events_enabled = JNI_FALSE;


static Tinfo*
find_tinfo(JNIEnv* jni, const char* thr_name) {
find_tinfo(JNIEnv* jni, const char* tname) {
Tinfo* inf = NULL;
int idx = 0;

// Find slot with named worker thread or empty slot
for (; idx < MAX_WORKER_THREADS; idx++) {
inf = &tinfo[idx];
if (inf->thr_name == NULL) {
inf->thr_name = thr_name;
if (inf->tname == NULL) {
inf->tname = tname;
break;
}
if (strcmp(inf->thr_name, thr_name) == 0) {
if (strcmp(inf->tname, tname) == 0) {
break;
}
}
@@ -97,83 +95,44 @@ find_method_depth(jvmtiEnv *jvmti, JNIEnv *jni, jthread vthread, const char *mna

static void
print_vthread_event_info(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jthread vthread, const char *event_name) {
jvmtiThreadInfo thr_info;
jvmtiError err = jvmti->GetThreadInfo(vthread, &thr_info);

if (err != JVMTI_ERROR_NONE) {
fatal(jni, "event handler failed during JVMTI GetThreadInfo call");
}
const char* thr_name = (thr_info.name == NULL) ? "<Unnamed thread>" : thr_info.name;
printf("\n#### %s event: thread: %s, vthread: %p\n", event_name, thr_name, vthread);
char* tname = get_thread_name(jvmti, jni, vthread);
Tinfo* inf = find_tinfo(jni, tname); // Find slot with named worker thread

Tinfo* inf = find_tinfo(jni, thr_name); // Find slot with named worker thread
printf("\n#### %s event: thread: %s, vthread: %p\n", event_name, tname, vthread);

if (strcmp(event_name, "VirtualThreadScheduled") == 0) {
inf->just_scheduled = JNI_TRUE;
}
else {
if (inf->thr_name == NULL && strcmp(event_name, "VirtualThreadTerminated") != 0) {
if (inf->tname == NULL && strcmp(event_name, "VirtualThreadTerminated") != 0) {
fatal(jni, "VThread event: worker thread not found!");
}
#if 0
if (continuation_events_enabled == JNI_TRUE && strcmp(event_name, "VirtualThreadMounted") == 0) {
if (!inf->just_scheduled) { // There is no ContinuationRun for just scheduled vthreads
if (inf->was_yield) {
fatal(jni, "VirtualThreadMounted: event with ContinuationYield before!");
}
if (inf->was_run) {
fatal(jni, "VirtualThreadMounted: event with ContinuationRun before!");
}
}
}
#endif
if (strcmp(event_name, "VirtualThreadUnmounted") == 0) {
if (inf->just_scheduled) {
fatal(jni, "VirtualThreadUnmounted: event without VirtualThreadMounted before!");
}
#if 0
if (continuation_events_enabled == JNI_TRUE && inf->was_run) {
fatal(jni, "VirtualThreadUnmounted: event with ContinuationRun before!");
}
if (continuation_events_enabled == JNI_TRUE && !inf->was_yield) {
fatal(jni, "VirtualThreadUnmounted: event without ContinuationYield before!");
}
#endif
}
inf->just_scheduled = JNI_FALSE;
}
inf->was_run = JNI_FALSE;
inf->was_yield = JNI_FALSE;
//deallocate(jvmti, jni, (void*)tname);
}

static void
print_cont_event_info(jvmtiEnv *jvmti, JNIEnv *jni, jthread vthread, jint frames_cnt, const char *event_name) {
print_cont_event_info(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jint frames_cnt, const char *event_name) {
static int cont_events_cnt = 0;
if (cont_events_cnt++ > MAX_EVENTS_TO_PROCESS) {
return; // No need to test all events
}

jvmtiThreadInfo thr_info;
jvmtiError err = jvmti->GetThreadInfo(vthread, &thr_info);
char* tname = get_thread_name(jvmti, jni, thread);
Tinfo* inf = find_tinfo(jni, tname); // Find slot with named worker thread

if (err != JVMTI_ERROR_NONE) {
fatal(jni, "event handler failed during JVMTI GetThreadInfo call");
}
const char* thr_name = (thr_info.name == NULL) ? "<Unnamed thread>" : thr_info.name;
printf("\n#### %s event: thread: %s, frames count: %d\n", event_name, thr_name, frames_cnt);
printf("\n#### %s event: thread: %s, frames count: %d\n", event_name, tname, frames_cnt);

Tinfo* inf = find_tinfo(jni, thr_name); // Find slot with named worker thread
if (inf->thr_name == NULL) {
if (inf->tname == NULL) {
fatal(jni, "Continuation event: worker thread not found!");
}
if (strcmp(event_name, "ContinuationRun") == 0) {
inf->was_run = JNI_TRUE;
inf->was_yield = JNI_FALSE;
}
if (strcmp(event_name, "ContinuationYield") == 0) {
inf->was_run = JNI_FALSE;
inf->was_yield = JNI_TRUE;
}
//deallocate(jvmti, jni, (void*)tname);
}

static void

0 comments on commit 0deb93b

Please sign in to comment.