Name: md23716 Date: 10/12/2001
According to the documentation of JVMPI, the JVMPI_EVENT_MONITOR_WAITED timeout value should return a finite value
in milliseconds, representing the actual time the thread has waited on the monitor. But the value returned is zero.
Problem occurs on all later versions of 1.2, 1.3.0 and 1.4.
Running...
java -Xrundev1 PingPong 2
Displays...
Event ID : 00767200: MONITOR_WAIT: Object : 02B79D38, Timeout : 0
Event ID : 0076F1F0: THREAD_START: Thread Name: Thread-1
It is not "FirstOne" ... Hence waiting on Integer ...
Event ID : 0076F1F0: MONITOR_WAIT: Object : 02B79D38, Timeout : 0
Event ID : 00770610: THREAD_START: Thread Name: Thread-2
It is not "FirstOne" ... Hence waiting on Integer ...
The timeout value should be a finite value in milliseconds, instead of zero.
Java code:
class PingPong extends Thread
{
String fWord;
int fDelay;
static int[] fFirstOne = new int[10];
PingPong(String whatToSay, int delayTime)
{
//System.out.println("Constructor\n");
fWord = whatToSay;
fDelay = delayTime;
}
public void run()
{
try
{
synchronized (fFirstOne)
{
if ( fWord.equals("FirstOne") )
{
fFirstOne[0] = 1;
System.out.println("Sleeping for 1 Second ....\n");
sleep(1000); //changed from 60 secs to 6 seconds ...
System.out.println("Notifying all ....\n");
fFirstOne.notifyAll();
}
else {
System.out.println("It is not \"FirstOne\" ... Hence waiting on Integer ...\n");
fFirstOne.wait();
}
}
System.out.println(fWord + " ");
System.out.flush();
}
catch (InterruptedException e)
{
System.out.println("Exception : Do Nothing here ...\n");
return;
}
}
public static void main(String[] args)
{
int count = 3;
if (args.length != 0)
{
// PingPong one = new PingPong("FirstOne", 0);
// one.start();
PingPong[] rest = new PingPong[count];
for (int i = 0; i < count; i++)
{
rest[i] = new PingPong("" + i, 0);
}
System.out.println(" Main sleeping for 1 second..");
try {
sleep(1000);
}
catch (InterruptedException e)
{
}
for (int i = 0; i < count; i++)
{
rest[i].start();
}
PingPong one = new PingPong("FirstOne", 0); // Code modified so that it can notify all waiting threads..
one.start();
}
else
{
int[] a = null;
System.gc();
for (int i = 0; i < 1000; i++)
{
a = new int[count];
}
System.out.println("");
System.gc();
}
}
}
C code:
#include <stdio.h>
#include <jvmpi.h>
#include <stdlib.h>
#define JVMPI(m) (jvmpi->m)
static JVMPI_Interface *jvmpi;
static void notify(JVMPI_Event *);
extern "C" JNIEXPORT jint JNICALL
JVM_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
int res = jvm->GetEnv((void **)&jvmpi, JVMPI_VERSION_1);
if (res < 0) {
return JNI_ERR;
}
jvmpi->NotifyEvent = notify;
JVMPI(EnableEvent)(JVMPI_EVENT_JVM_INIT_DONE, NULL);
JVMPI(EnableEvent)(JVMPI_EVENT_THREAD_START, NULL);
JVMPI(EnableEvent)(JVMPI_EVENT_MONITOR_WAIT, NULL);
JVMPI(EnableEvent)(JVMPI_EVENT_MONITOR_WAITED, NULL);
if (options && *options) {
int val = atoi(options);
if (val) {
printf("value (val) is true or greater than one\n");
// delay = val;
}
}
return JNI_OK;
}
static bool inited;
void
notify(JVMPI_Event * event)
{
switch (event->event_type) {
case JVMPI_EVENT_JVM_INIT_DONE:
inited = true;
break;
case JVMPI_EVENT_THREAD_START:
printf("Event ID : %p: THREAD_START: Thread Name: %s\n",
event->u.thread_start.thread_env_id,
event->u.thread_start.thread_name);
break;
case JVMPI_EVENT_MONITOR_WAIT:
if (inited) {
printf("Event ID : %p: MONITOR_WAIT: Object : %p, Timeout : %ld\n",
event->env_id,
event->u.monitor_wait.object,
(long) event->u.monitor_wait.timeout);
}
break;
case JVMPI_EVENT_MONITOR_WAITED:
if (inited) {
printf("Event ID : %p: MONITOR_WAITED: Object %p, Timeout : %ld\n",
event->env_id,
event->u.monitor_wait.object,
(long) event->u.monitor_wait.timeout);
}
break;
default:
break;
}
}
======================================================================