JDK-4514097 : JVMPI_MONITOR_WAITED value returned is wrong
  • Type: Bug
  • Component: vm-legacy
  • Sub-Component: jvmpi
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2001-10-12
  • Updated: 2003-08-15
  • Resolved: 2003-05-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other Other
1.3.1_09 09Fixed 1.4.1_05Fixed 1.4.2Fixed
Related Reports
Relates :  
Description

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;
    }
}
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.3.1_09 1.4.1_05 mantis-rc FIXED IN: 1.3.1_09 1.4.1_05 mantis-rc tiger INTEGRATED IN: 1.3.1_09 1.4.1_05 mantis-b24 mantis-rc tiger tiger-b08 VERIFIED IN: 1.4.1_05
23-07-2004

PUBLIC COMMENTS .
23-07-2004

SUGGESTED FIX the following change will measure the time spent in waiting for monitor ------- objectMonitor_win32.cpp ------- *** /tmp/sccs.jxaaCB Fri May 2 17:47:55 2003 --- objectMonitor_win32.cpp Fri May 2 17:47:49 2003 *************** *** 227,232 **** --- 227,237 ---- if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAIT)) { jvmpi::post_monitor_wait_event((oop)object(), millis); } + DWORD start_wait; + DWORD end_wait; + if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { + start_wait = GetTickCount(); + } { assert(THREAD->is_Java_thread(), "Must be Java thread!"); ThreadBlockInVM tbiv((JavaThread*) THREAD); *************** *** 235,243 **** // retain CONDVAR_WAIT state until re-enter successfully completes raw_enter(THREAD, false); // re-enter the monitor } ! if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { ! jvmpi::post_monitor_waited_event((oop)object(), millis); } _recursions = save; // restore the old recursion count _waiters--; // decrement the number of waiters --- 240,249 ---- // retain CONDVAR_WAIT state until re-enter successfully completes raw_enter(THREAD, false); // re-enter the monitor } ! if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { ! end_wait = GetTickCount(); ! jvmpi::post_monitor_waited_event((oop)object(), end_wait - start_wait); } _recursions = save; // restore the old recursion count _waiters--; // decrement the number of waiters ------- objectMonitor_solaris.cpp ------- *** /tmp/sccs.MMayCB Fri May 2 17:48:54 2003 --- objectMonitor_solaris.cpp Fri May 2 16:15:58 2003 *************** *** 308,313 **** --- 308,318 ---- if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAIT)) { jvmpi::post_monitor_wait_event((oop)object(), millis); } + hrtime_t start_wait; + hrtime_t end_wait; + if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { + start_wait = gethrtime(); + } { assert(THREAD->is_Java_thread(), "Must be Java thread!"); JavaThread* javathread = (JavaThread*) THREAD; *************** *** 326,332 **** } if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { ! jvmpi::post_monitor_waited_event((oop)object(), millis); } _recursions = save; // restore the old recursion count _waiters--; // decrement the number of waiters --- 331,339 ---- } if (jvmpi::is_event_enabled(JVMPI_EVENT_MONITOR_WAITED)) { ! end_wait = gethrtime(); ! jvmpi::post_monitor_waited_event((oop)object(), ! (end_wait - start_wait)/1000000L); } _recursions = save; // restore the old recursion count _waiters--; // decrement the number of waiters ###@###.### 2003-05-02
02-05-2003

EVALUATION the current code return the parameter passed into wait instead of the actuall time spent in waiting. ###@###.### 2003-05-02
02-05-2003