В Solaris лучше не пишите свой собственный код для этого (ни в SPARC, ни в x86);вместо этого используйте функции atomic_cas(3C)
для следующих целей:
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
switch (size) {
case 1: return atomic_cas_8(ptr, (unsigned char)old, (unsigned char)new);
case 2: return atomic_cas_16(ptr, (unsigned short)old, (unsigned short)new);
case 4: return atomic_cas_32(ptr, (unsigned int)old, (unsigned int)new);
#ifdef _LP64
case 8: return atomic_cas_64(ptr, old, new);
#endif
default: break;
}
return old;
}
Это подойдет для Solaris.
Редактировать: , если выОбязательно нужно указать на это, инструкция SPARC (v8 +, также известная как UltraSPARC) - это «сравнить и поменять местами», или 1011 *.Это всегда атомарно (sparc не знает префиксов блокировки).Он поставляется только в 32-битном и 64-битном (CASX
) вариантах, так что 8/16-битные библиотечные функции выполняют 32-битные CAS
, маскируя нецелевое слово / байты.Я не буду помогать с повторной реализацией этого - это не очень хорошая идея, используйте интерфейсы библиотеки.
Edit2: Некоторую помощь с повторной реализацией вы получите, читая исходный код (если вы не можете связаться с Solaris libc).