slowLockMutex / putHeavyLock

Maxim Kizub M.Kizub at post.skynet.lt
Thu Nov 30 01:40:50 PST 2000


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello Godmar,

Wednesday, November 29, 2000, 10:01:35 PM, you wrote:


>>
>>   I have sometimes assertion erros
>> from putHeavyLock method in
>>         assert(*lkp == LOCKINPROGRESS);
>>
>> So, the question is - how lkp is
>> supposed to be protected in current thread
>> from being modified from others threads?
>>

GB> Which COMPARE_AND_EXCHANGE macro does it use?

GB> Do you have a backtrace when that assert fails?

Let me try. But note - sometimes I had asserts
related to synchronization, and they were "false".
I mean, I have a dual processor machine, and,
for example, and asseret
assert(xxx==0 && yyy==0)
was caught, but debugger shows, that both
xxx and yyy are nulls. Probably, that's
because of my dual-processor computer...

So, about slowLockMutex. For example,
I try test burford.java. Assertion failed on
third run. The thread that failed assertion was:
- --------- Thread 0 ---------------
_assert(void * 0x1007cc48, void * 0x1007cc20, unsigned int
0x000000a6) line 256
putHeavyLock(_iLock * * 0x10082454 struct _iLock *  gc_lock, _iLock *
0x1007cb3c) line 166 + 28 bytes
slowLockMutex(_iLock * * 0x10082454 struct _iLock *  gc_lock, void *
0x00fbf9a8) line 219 + 13 bytes
_lockMutex(_iLock * * 0x10082454 struct _iLock *  gc_lock, void *
0x00fbf9a8) line 476 + 13 bytes
gc_heap_malloc(unsigned int 0x00000014) line 290 + 19 bytes
gcMalloc(_Collector * 0x100826f8 gc_obj, unsigned int 0x0000000c, int
0x00000009) line 867 + 12 bytes
setupGlobalRegisters() line 1062 + 34 bytes
prologue(_methods * 0x005ef0a0) line 210
translate(_methods * 0x005ef0a0, _errorInfo * 0x00fbfba4) line 290 +
9 bytes
soft_fixup_trampoline(void * * 0x0060e315) line 570 + 13 bytes
i386_do_fixup_trampoline() line 32
_sysdepCallMethod(void * 0x1004df01) line 84
00fbfecc()
do_execute_java_method_v(void * 0x005dbbb8, const char * 0x1007dc2c,
const char * 0x1007dc28, _methods * 0x005751e0, int 0x00000000, char
* 0x00fbff50) line 150 + 36 bytes
do_execute_java_method(void * 0x005dbbb8, const char * 0x1007dc2c,
const char * 0x1007dc28, _methods * 0x00000000, int 0x00000000) line
164 + 29 bytes
exitThread() line 425 + 25 bytes
firstStartThread(void * 0x005dbbb8) line 391
start_me_up(void * 0x0063c938) line 564 + 52 bytes
KERNEL32! 77e837cd()
- ---------------------------------
as you see - it tryes to finish, i.e.
do_execute_java_method(getCurrentThread(), "finish", "()V", 0, 0);
it's status:
"running"
"stop disallowed = 4" (i.e. stop was disallowed 4 times)
"stop pending=0"


Next thread:
- ------------- Thread 1 ------------
NTDLL! 77f82152()
KERNEL32! 77e83126()
slowLockMutex(_iLock * * 0x100868b0 struct _iLock *  translatorlock,
void * 0x00ebf6f0) line 220 + 16 bytes
_lockMutex(_iLock * * 0x100868b0 struct _iLock *  translatorlock,
void * 0x00ebf6f0) line 476 + 13 bytes
translate(_methods * 0x005dbd08, _errorInfo * 0x00ebf778) line 191 +
19 bytes
soft_fixup_trampoline(void * * 0x00571d6d) line 570 + 13 bytes
i386_do_fixup_trampoline() line 32
00ebfa70()
execute_java_constructor_v(const char * 0x1007ccbc,
Hjava_lang_ClassLoader * 0x00000000, Hjava_lang_Class * 0x00572430,
const char * 0x1007ccb8, char * 0x00ebfaf8) line 271 + 36 bytes
execute_java_constructor(const char * 0x1007ccbc,
Hjava_lang_ClassLoader * 0x00000000, Hjava_lang_Class * 0x00000000,
const char * 0x1007ccb8) line 284 + 25 bytes
slowUnlockMutex(_iLock * * 0x005edeec, void * 0x00ebfb44) line 247 +
19 bytes
slowUnlockObject(Hjava_lang_Object * 0x005edee8, void * 0x00ebfb44)
line 521 + 16 bytes
0059569f()
0055d54b()
005955d3()
_sysdepCallMethod(void * 0x1004df01) line 84
00ebfe64()
Kaffe_CallVoidMethodV(JNIEnv_ * 0x1007b938 struct JNIEnv_ 
Kaffe_JNIEnv, void * 0x005dbf38, void * 0x00575554, char *
0x00ebff64) line 1082 + 72 bytes
Kaffe_CallVoidMethod(JNIEnv_ * 0x1007b938 struct JNIEnv_ 
Kaffe_JNIEnv, void * 0x005dbf38, void * 0x00575554) line 1095 + 21
bytes
firstStartThread(void * 0x005dbf38) line 357 + 28 bytes
start_me_up(void * 0x0063c910) line 564 + 52 bytes
KERNEL32! 77e837cd()
- -----------------------------------

it tryes to do next (in slowUnlockMutex)
        /* Only the lock holder can be doing an unlock */
        if (!jthread_on_current_stack(lk->holder)) {
                putHeavyLock(lkp, lk);
                jthread_enable_stop();
>>>             throwException(IllegalMonitorStateException);
        }


next thread is finalizer, it simply waits.
- -------------- Thread 2 ------------
NTDLL! 77f82152()
KERNEL32! 77e83126()
_waitCond(_iLock * * 0x10082488 struct _iLock *  finman, __int64
0x0000000000000000) line 365 + 20 bytes
finaliserMan(void * 0x100826f8 gc_obj) line 764 + 14 bytes
startSpecialThread(void * 0x005db2f8) line 274 + 9 bytes
start_me_up(void * 0x005ac6e0) line 564 + 52 bytes
KERNEL32! 77e837cd()
- -----------------------------------

next thread - GC?
- -------------- Threas 3 -----------
NTDLL! 77f82152()
KERNEL32! 77e83126()
_waitCond(_iLock * * 0x10082450 struct _iLock *  gcman, __int64
0x0000000000000000) line 365 + 20 bytes
gcMan(void * 0x100826f8 gc_obj) line 434 + 14 bytes
startSpecialThread(void * 0x005db218) line 274 + 9 bytes
start_me_up(void * 0x005eb978) line 564 + 52 bytes
KERNEL32! 77e837cd()
- ----------------------------------

next thread (main thread)
- ------------- Thread 4 -------------
NTDLL! 77f82152()
KERNEL32! 77e83126()
slowLockMutex(_iLock * * 0x100868b0 struct _iLock *  translatorlock,
void * 0x0012f65c) line 220 + 16 bytes
_lockMutex(_iLock * * 0x100868b0 struct _iLock *  translatorlock,
void * 0x0012f65c) line 476 + 13 bytes
translate(_methods * 0x005754ec, _errorInfo * 0x0012f6e4) line 191 +
19 bytes
soft_fixup_trampoline(void * * 0x00570f5d) line 570 + 13 bytes
i386_do_fixup_trampoline() line 32
005dbcd4()
005f1c03()
_sysdepCallMethod(void * 0x1004df01) line 84
0012fa84()
Kaffe_CallStaticVoidMethodV(JNIEnv_ * 0x1007b938 struct JNIEnv_ 
Kaffe_JNIEnv, void * 0x005fc1b0, void * 0x00601b7c, char *
0x0012fb34) line 2356 + 34 bytes
JNIEnv_::CallStaticVoidMethod(JNIEnv_ * const 0x1007b938 struct
JNIEnv_  Kaffe_JNIEnv, void * 0x005fc1b0) line 810 + 29 bytes
main2(JNIEnv_ * 0x1007b938 struct JNIEnv_  Kaffe_JNIEnv, char * *
0x003a1220, int 0x00000004, int 0x00000000) line 275 + 24 bytes
main(int 0x00000001, char * * 0x003a1220) line 153 + 24 bytes
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 77e992a6()
- ----------------------------------


next thread
- -------------- Thread 5 ---------
NTDLL! 77f82152()
KERNEL32! 77e83126()
_waitCond(_iLock * * 0x0059660c, __int64 0x0000000000000000) line 365
+ 20 bytes
java_lang_Object_wait0(Hjava_lang_Object * 0x00596608, __int64
0x0000000000000000) line 97 + 20 bytes
0053ff43()
006349fb()
005e6631()
005dbe94()
0063f89a()
005955d3()
_sysdepCallMethod(void * 0x1004df01) line 84
00dbfe64()
Kaffe_CallVoidMethodV(JNIEnv_ * 0x1007b938 struct JNIEnv_ 
Kaffe_JNIEnv, void * 0x005dafe8, void * 0x00575554, char *
0x00dbff64) line 1082 + 72 bytes
Kaffe_CallVoidMethod(JNIEnv_ * 0x1007b938 struct JNIEnv_ 
Kaffe_JNIEnv, void * 0x005dafe8, void * 0x00575554) line 1095 + 21
bytes
firstStartThread(void * 0x005dafe8) line 357 + 28 bytes
start_me_up(void * 0x0063c730) line 564 + 52 bytes
KERNEL32! 77e837cd()
- --------------------------------

Program output at this moment was:
- ------------
Starting burford...
Starting feeders...
- ------------

but it looks like at least one feeder already done
it's job.

Ok, I hope this will help.
BTW, I see now that this is a secondary error,
because one of threads tryes to throw an
error "IllegalMonitorState", but anyway -
1. why program has caused it?
2. even if it throws an error - it's not
the reason to cause assertion fail.
3. Take, for example, this code:
/*
 * Lock a mutex - try to do this quickly but if we failed because
 * we can't determine if this is a multiple entry lock or we've got
 * contention then fall back on a slow lock.
 */
void
_lockMutex(iLock** lkp, void* where)
{
        uintp val;

        val = (uintp)*lkp;

        if (val == 0) {
                if (!COMPARE_AND_EXCHANGE(lkp, 0, (iLock*)where)) {
                        slowLockMutex(lkp, where);
                }
        }
        else if (val - (uintp)where > 1024) {
                /* XXX count this in the stats area */
                slowLockMutex(lkp, where);
        }
}

as you see - lkp is not protected at all.
If val != 0, this doesn't mean that in next
statement it's != 0, i.e. in this time another
thread may execute some code to change lkp.
Actually, all code related to lkp must be under
jthread_spinon/jthread_spinoff protection, right?

- --
Best regards,
 Maxim                            mailto:M.Kizub at post.skynet.lt

-----BEGIN PGP SIGNATURE-----
Version: PGP 6.5i

iQA/AwUBOiYSm+w5enpENJF+EQLwLQCg9q0v733+YMD4UaH4mD4lzuFazicAoK+D
W3YeW5FUhWli9V73en0GA+/Q
=QrEF
-----END PGP SIGNATURE-----




More information about the kaffe mailing list