/* * Use 4 byte cas instruction to achieve 2 byte xchg. Main logic * here is to get the bit shift of the byte we are interested in. * The XOR is handy for reversing the bits for big-endian byte order.
*/ staticinlineunsignedlong
xchg16(__volatile__ unsignedshort *m, unsignedshort val)
{ unsignedlong maddr = (unsignedlong)m; int bit_shift = (((unsignedlong)m & 2) ^ 2) << 3; unsignedint mask = 0xffff << bit_shift; unsignedint *ptr = (unsignedint *) (maddr & ~2); unsignedint old32, new32, load32;
/* Read the old value */
load32 = *ptr;
do {
old32 = load32;
new32 = (load32 & (~mask)) | val << bit_shift;
load32 = __cmpxchg_u32(ptr, old32, new32);
} while (load32 != old32);
/* * Atomic compare and exchange. Compare OLD with MEM, if identical, * store NEW in MEM. Return the initial value in MEM. Success is * indicated by comparing RETURN with OLD.
*/
/* * Use 4 byte cas instruction to achieve 1 byte cmpxchg. Main logic * here is to get the bit shift of the byte we are interested in. * The XOR is handy for reversing the bits for big-endian byte order
*/ staticinlineunsignedlong
__cmpxchg_u8(volatileunsignedchar *m, unsignedchar old, unsignedcharnew)
{ unsignedlong maddr = (unsignedlong)m; int bit_shift = (((unsignedlong)m & 3) ^ 3) << 3; unsignedint mask = 0xff << bit_shift; unsignedint *ptr = (unsignedint *) (maddr & ~3); unsignedint old32, new32, load; unsignedint load32 = *ptr;
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid cmpxchg(). */ void __cmpxchg_called_with_bad_pointer(void);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.