[kaffe] COMPARE_AND_EXCHANGE with m68k

Dalibor Topic robilad@yahoo.com
Tue Feb 25 00:00:02 2003


hi Tony,

--- Tony Wyatt <wyattaw@optusnet.com.au> wrote:

> Clearly this can not be put into the source tree,
> and with Dalibor snapping
> at my heels to post my patches, I am asking for
> help. I can see two ways out
> of this, can anyone suggest the best way?

I've looked at the pocketlinux tree, and the way they
handle it for m68k is that they use the slow C
implementation (i.e. there is no COMPARE_AND_EXCHANGE
OR ATOMIC_EXCHANGE on m68k on pocketlinux).

that might be a temporary solution for the amiga (and
linux, if it has the same problem on m68k).

here's the relevant bit from 'porting Kaffe':

 2.4. Locks subsystem

Kaffe Fast Locking scheme (read FAQ/FAQ.locks) need a
macro to atomic compare and exchange a lock address.
This macro COMPARE_AND_EXCHANGE() must be implemented
in assembler.

Macro COMPARE_AND_EXCHANGE() should be define in file
config/$Khost_cpu/common.h. It is only used into file
kaffe/kaffevm/locks.c.

If you can't implement it but have an atomic exchange
instruction, defines macro ATOMIC_EXCHANGE() as in
Sparc port.

Otherwise, fall back to plain C implementations as in
MIPS I port. You should note that it will fail on a
multi-processors machine. 

(more on
http://egp.free.fr/port-kaffe/port-kaffe-0.2.html ).

here's kaffe's COMPARE_AND_EXCHANGE from mips:
/*
 * Do an atomic compare and exchange.  The address 'A'
is checked against
 * value 'O' and if they match it's exchanged with
value 'N'.
 * We return '1' if the exchange is sucessful,
otherwise 0.
 */
#define COMPARE_AND_EXCHANGE(A,O,N)             \
({                                              \
    int ret = 0;                                \
    jthread_suspendall();                       \
                                                \
    if (*(A) == (O)) {                          \
        *(A) = (N);                             \
        ret = 1;                                \
    }                                           \
    jthread_unsuspendall();                     \
    ret;                                        \
})



and this is the way it's implemented in pocketlinux'
locks.c:

27              /*
 28               * If we don't have an atomic compare
and exchange defined then make one
 29               * out of a simple atmoc exchange
(using the LOCKINPROGRESS value the place
 30               * holder).  If we don't have that,
we'll just fake it.
 31               */
 32              #if !defined(COMPARE_AND_EXCHANGE)
 33              #if defined(ATOMIC_EXCHANGE)
 34              #define	COMPARE_AND_EXCHANGE(A,O,N) \
 35              	({ \
 36              		iLock* val = LOCKINPROGRESS; \
 37              		ATOMIC_EXCHANGE((A), val); \
 38              		if (val == (O)) { \
 39              			*(A) = (N); \
 40              		} \
 41              		else { \
 42              			*(A) = (O); \
 43 jsantala 1.1 		} \
 44              		(val == (O) ? 1 :  0); \
 45              	})
 46              #else
 47              inline
 48              int
 49              slowCompareAndExchange(iLock** a,
iLock** o, iLock* n)
 50              {
 51              	int val;
 52              	Kaffe_TI_enterCritSect();
 53              	if (*a == o) {
 54              		*a = n;
 55              		val = 1;
 56              	}
 57              	else {
 58              		val = 0;
 59              	}
 60              	Kaffe_TI_exitCritSect();
 61              	return (val);
 62              }
 63              #define	COMPARE_AND_EXCHANGE(A,O,N) \
 64 jsantala 1.1 	slowCompareAndExchange(A, O, N)
 65              #endif
 66              #endif

I hope that someone from the m68k community has a
better proposal, of course.

cheers,
dalibor topic

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/