Places object in freelist if it is of one of the precribed sizes, otherwise it frees it from the OS managed heap Returns: None
| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzSMAR::Free | (uint32_t,uint32_t,) |
Declared in file: hzSMAR.h
Defined in file : hzSMAR.cpp
Function Logic:
Function body:
hzEcode hzSMAR::Free (uint32_t ssrAddr)uint32_t nSize,
{
// Places object in freelist if it is of one of the precribed sizes, otherwise it frees it from the OS managed heap
//
// Arguments: 1) pMemobj A pointer to what is assumed to be string space to be freed
// 2) nSize The size of the string space
//
// Returns: None
_hzfunc("hzSMAR::Free") ;
_smarBloc* pBloc ; // Pointer to superblock
uchar* pItem ; // For heap allocations, start of string space
uint32_t* pSlot ; // Start of string space (as freelist entry)
uint32_t nUnit ; // Number of 4-byte units in string being freed
uint32_t blocNo ; // Offset within vector of blocks
uint32_t slotNo ; // String slot within block
if (!this) hzexit(E_CORRUPT, "No instance") ;
if (!ssrAddr) hzexit(E_CORRUPT, "NULL address") ;
if (!nSize) hzexit(E_CORRUPT, "Freeing zero size item %u:%u", blocNo, slotNo) ;
slotNo = ssrAddr & SMAR_SLOT_MASK ;
blocNo = (ssrAddr & SMAR_BLOC_MASK) >> 16;
if (blocNo > m_Super.Count())
{
threadLog("SMAR %u: ILLEGAL ADDR: Size %u, addr %u:%u\n", m_nCode, nSize, blocNo, slotNo) ;
return E_CORRUPT ;
}
if (!blocNo || nSize >&eq; SMAR_OVERSIZE)
{
// Heap
pItem = (uchar*) m_Heap[ssrAddr-1];
threadLog("SMAR %u: HEAP FREE: Size %u, addr %u:%u (ptr %p)\n", m_nCode, nSize, blocNo, slotNo, pItem) ;
delete pItem ;
m_Heap.Delete(ssrAddr-1);
return E_OK ;
}
// Item is within allocation regime
pBloc = m_Super[blocNo] ;
if (!pBloc)
{ threadLog("SMAR %u: CORRUPT: No block found for address %u:%u. Total of %u superblocks issued)\n", m_nCode, blocNo, slotNo, m_Super.Count()) ; return E_MEMORY ; }
if (pBloc->m_blkSelf != blocNo)
{ threadLog("SMAR %u: CORRUPT: Address %u:%u. Block does not self-address (%u))\n", m_nCode, blocNo, slotNo, pBloc->m_blkSelf) ; return E_MEMORY ; }
pSlot = pBloc->m_Space ;
pSlot += slotNo ;
// When freeing a slot, the slot must be valid - i.e. the first uint32_t in the slot must be non-zero
if (!pSlot[0])
{ threadLog("SMAR %u: CORRUPT: Address %u:%u has empty header (already deleted)\n", m_nCode, blocNo, slotNo) ; return E_MEMORY ; }
// Set the first part to zero to mark the delete
pSlot[0]= 0;
// Don't free slots during shutdown
if (_hzGlobal_kill)
return E_OK ;
// Calculate units
nUnit = (nSize/4)+ (nSize%4? 1:0);
if (nUnit < 2)
nUnit = 2;
m_lockFlist.Lock() ;
if (m_arrFL[nUnit])
{
// Check if this value is valid
blocNo = (m_arrFL[nUnit] & SMAR_BLOC_MASK) >> 16;
if (blocNo > m_Super.Count())
{
threadLog("SMAR %u: ILLEGAL OLD ADDR: Size %u (unit %u), blk pop %u, addr %u:%u (called by %s)\n", m_nCode, nSize, nUnit, m_Super.Count(), blocNo, slotNo, _hzCaller()) ;
m_lockFlist.Unlock() ;
return E_MEMORY ;
}
}
pSlot[1]= m_arrFL[nUnit] ;
m_arrFL[nUnit] = ssrAddr ;
m_lockFlist.Unlock() ;
return E_OK ;
}