/* enqueue src at the _end_ of the receiver's queue */ virtual void enqueue(MM_HeapRegionQueue *srcAsPQ) { MM_LockingHeapRegionQueue* src = MM_LockingHeapRegionQueue::asLockingHeapRegionQueue(srcAsPQ); if (NULL == src->_head) { /* Nothing to move - single read needs no lock */ return; } lock(); src->lock(); /* Remove from src */ MM_HeapRegionDescriptorSegregated *front = src->_head; MM_HeapRegionDescriptorSegregated *back = src->_tail; uintptr_t srcLength = src->_length; src->_head = NULL; src->_tail = NULL; src->_length = 0; /* Add to back of self */ front->setPrev(_tail); /* OK even if _tail is NULL */ if (_tail == NULL) { _head = front; } else { _tail->setNext(front); } _tail = back; _length += srcLength; src->unlock(); unlock(); }
/* * This method should be used with care. In particular, it is wrong to detach from a freelist * while iterating over it unless the detach stops further iteration. */ void detachInternal(MM_HeapRegionDescriptorSegregated *cur) { _length--; MM_HeapRegionDescriptorSegregated *prev = cur->getPrev(); MM_HeapRegionDescriptorSegregated *next = cur->getNext(); if (prev != NULL) { Assert_MM_true(prev->getNext() == cur); prev->setNext(next); } else { Assert_MM_true(cur == _head); } if (next != NULL) { Assert_MM_true(next->getPrev() == cur); next->setPrev(prev); } else { Assert_MM_true(cur == _tail); } cur->setPrev(NULL); cur->setNext(NULL); if (_head == cur) { _head = next; } if (_tail == cur) { _tail = prev; } }
virtual void push(MM_FreeHeapRegionList *srcAsFPL) { MM_LockingFreeHeapRegionList* src = MM_LockingFreeHeapRegionList::asLockingFreeHeapRegionList(srcAsFPL); if (src->_head == NULL) { /* Nothing to move - single read needs no lock */ return; } lock(); src->lock(); /* Remove from src */ MM_HeapRegionDescriptorSegregated *front = src->_head; MM_HeapRegionDescriptorSegregated *back = src->_tail; uintptr_t srcLength = src->_length; src->_head = NULL; src->_tail = NULL; src->_length = 0; /* Add to front of self */ back->setNext(_head); /* OK even if _head is NULL */ if (_head == NULL) { _tail = back; } else { _head->setPrev(back); } _head = front; _length += srcLength; src->unlock(); unlock(); }
void pushInternal(MM_HeapRegionDescriptorSegregated *region) { Assert_MM_true(NULL == region->getNext() && NULL == region->getPrev()); _length++; if (NULL == _head) { _head = region; _tail = region; } else { _head->setPrev(region); region->setNext(_head); _head = region; } }
MM_HeapRegionDescriptorSegregated *dequeueInternal() { MM_HeapRegionDescriptorSegregated *result = _head; if (_head != NULL) { _length--; _head = result->getNext(); result->setNext(NULL); if (NULL == _head) { _tail = NULL; } else { _head->setPrev(NULL); } } return result; }