void fox_heap_Block::freeSpace(fox_heap_Space* pSpace) { KASSERT(pSpace->getBlock() == this); this->checkValidSpace(pSpace); fox_heap_Space* pNext; #if SPIN_LOCK_EACH_BLOCK lock(); this->m_cntAlloc --; pNext = this->m_pFree; pSpace->setNextFree(pNext); m_pFree = pSpace; if (pNext == ADDR_ZERO) { m_pOwner->pushAvailableBlock(this); } unlock(); #else while (true) { pNext = this->m_pFree; pSpace->setNextFree(pNext); if (fox_util_cmpxchg32(&m_pFree, (int)pSpace, (int)pNext)) { break; } } if (pNext == ADDR_ZERO) { m_pOwner->pushAvailableBlock(this); } #endif }
fox_heap_Space* fox_heap_Block::allocSpace() { fox_heap_Space* pSpace; #if SPIN_LOCK_EACH_BLOCK lock(); pSpace = this->m_pFree; KASSERT(pSpace != ADDR_ZERO); #ifdef _DEBUG if (pSpace->getNext() != ADDR_ZERO) { this->checkValidSpace(pSpace->getNext()); } #endif this->m_pFree = pSpace->getNext(); this->m_cntAlloc ++; unlock(); #else while (true) { if ((pSpace = this->m_pFree) == ADDR_ZERO) { break; } fox_heap_Space* pNext = pSpace->getNext(); if (fox_util_cmpxchg32(&m_pFree, (int)pNext, (int)pSpace)) { fox_util_inc32(&m_cntAlloc); break; } } #endif return pSpace; }
//FOX_NAKED void fm::SafeInstanceQ::insert(fastiva_Instance_p pNewRoot, fastiva_Instance_p pEnd) { #if 1 //def _ARM_ while (true) { fastiva_Instance_p pFirst = this->m_pFirst; pEnd->m_pNext$ = pFirst; /** pNewEntry->m_pNext$ 는 순간적으로 변경될 수 있으므로, 반드시 pFirst를 사용할 것 */ if (fox_util_cmpxchg32(&this->m_pFirst, (int)pNewRoot, (int)pFirst)) { break; } } #else _asm { push ebx; mov ebx, [esp + 8]; mov eax, [ecx].m_pFirst; set_next_entry: mov [ebx].m_pNext$, eax; FOX_ASM_LOCK cmpxchg [ecx].m_pFirst, edx // 여러 thread에서 동일한 instance를 추가하여도 무방. jne set_next_entry; pop ebx; ret 4; } #endif }
java_util_concurrent_atomic_AtomicReferenceFieldUpdater::compareAndSet( // java_util_concurrent_atomic_AtomicReferenceFieldUpdater_p self, java_lang_Object_p& field, jint int2, java_lang_Object_p expected, java_lang_Object_p update ) { return fox_util_cmpxchg32(field, (int)update, (int)expected); }