Race condition in linkClass with native threads

Frank Mehnert Frank.Mehnert at mchp.siemens.de
Wed Mar 19 07:12:27 PST 1997


Hi,

currently I'm continue porting kaffe to Chorus with native threads. Just
now I found a race condition in linkClass (file classMethod.c, kaffe
version 0.8.2):

One thread can verify a prepared class:

	prepareClass (class);

	/* Second stage class verification - check the class format is okay */
	verify2(class);


After that the class will be linked:

	/* Load (only) all classes references in the constant pool.
	 * Replace each CONSTANT_Class by a CONSTANT_ResolvedClass. */
	pool = CLASS_CONSTANTS (class);
	for (i = 0;  i < pool->size; i++) {
		switch (pool->tags[i]) {
		case CONSTANT_Class:
=== may block =======> 	pool->data[i] = (ConstSlot)getClass (i, class);
			pool->tags[i] = CONSTANT_ResolvedClass;
			break;
		case CONSTANT_String:
			idx = CLASS_CONST_USHORT1(class, i);
			pool->data[i] = (ConstSlot)Utf8Const2JavaString (WORD2UTF (pool->data[idx]));
			break;
		}
	}

A verify2 after this give us an error. So if our thread preempts in this
loop (in getClass) and another thread want to check this class - it gets
an ClassFormatError.

I think this occurs only with native threads. So I would to propose for
the following solution:

file kaffe/kaffevm/classMethod.h:
=================================
26,29c26,28
< #define CSTATE_DOING_LINK       3
< #define CSTATE_LINKED           4
< #define CSTATE_DOINGINIT        5
< #define CSTATE_OK               6
---
> #define CSTATE_LINKED           3
> #define CSTATE_DOINGINIT        4
> #define CSTATE_OK               5

file kaffe/kaffevm/classMethod.c:
=================================
490,496d489
<     if (class->state == CSTATE_DOING_LINK) {    
<             while (class->state == CSTATE_DOING_LINK) {
<                 suspendThread(currentThread);
<             }
<             return;
<         }
< 
502,504d494
<     /* signal that we are linking */
<     class->state = CSTATE_DOING_LINK;
< 
566c556
< DBG(    printf("Initialising %s static %d\n", class->name->data,
CLASS_FSIZE(class));
---
> DBG(    printf("Initialising %s static %d\n", class->name,
CLASS_SSIZE(class));


May be there are more of these 'bugs'...

Searching,
            Frank

Frank Mehnert
email: Frank.Mehnert at mchp.siemens.de



More information about the kaffe mailing list