Allocate string space. The actual space allocated will be sufficient for a string of length nSize, plus the copy count, length indicator and NULL terminator.
| Return Type | Function name | Arguments |
|---|---|---|
| uint32_t | hzSMAR::Alloc | (uint32_t,) |
Declared in file: hzSMAR.h
Defined in file : hzSMAR.cpp
Function Logic:
Function body:
uint32_t hzSMAR::Alloc (uint32_t nSize)
{
// Allocate string space. The actual space allocated will be sufficient for a string of length nSize, plus the copy count, length indicator and NULL terminator.
//
// Argument: nSize Required string length (excluding copy count, length indicator and null terminator)
//
// Returns: Pointer to the required string space. If is a fatal condition if this cannot be obtained.
_hzfunc("hzSMAR::Alloc") ;
_smarBloc* pBloc = 0; // Pointer to superblock
void* pVoid ; // Heap addresses only
uint32_t* pSlot = 0; // Pointer to freelist slot
uint32_t ssrAddr = 0; // New slot address
uint32_t nUnit ; // Number of 4/8-byte units required
uint32_t blocNo ; // Offset within vector of blocks
uint32_t slotNo ; // String slot within block
bool bNote = false ; // Set if a new block is created
if (!this)
hzexit(E_CORRUPT, "No instance") ;
if (!nSize)
hzexit(E_NODATA, "Cannot allocate a zero size string") ;
// Deal with oversized allocations
if (nSize >&eq; SMAR_OVERSIZE)
{
nUnit = (nSize/8)+ (nSize%8? 1:0);
ssrAddr = m_Heap.Count() + 1;
pVoid = new char[nUnit * 8];
m_Heap.Insert(ssrAddr, pVoid) ;
return ssrAddr ;
}
// String not oversized
nUnit = (nSize/4)+ (nSize%4? 1:0);
if (nUnit < 2)
nUnit = 2;
// Is there a free list for the exact size?
m_lockFlist.Lock() ;
if (m_arrFL[nUnit])
{
ssrAddr = m_arrFL[nUnit] ;
slotNo = ssrAddr & SMAR_SLOT_MASK ;
blocNo = (ssrAddr & SMAR_BLOC_MASK) >> 16;
if (blocNo == 0|| blocNo > m_Super.Count())
{
hzerr(E_CORRUPT, "SMAR %u: Case 1 ILLEGAL SLot Address %u:%u (units %u)", m_nCode, blocNo, slotNo, nUnit) ;
m_arrFL[nUnit] = 0;
m_lockFlist.Unlock() ;
goto top ;
}
pBloc = m_Super[blocNo] ;
if (!pBloc)
{
hzerr(E_CORRUPT, "SMAR %u: Case 2 ILLEGAL SLot Address %u:%u (units %u)", m_nCode, blocNo, slotNo, nUnit) ;
m_arrFL[nUnit] = 0;
m_lockFlist.Unlock() ;
goto top ;
}
pSlot = pBloc->m_Space + slotNo ;
m_arrFL[nUnit] = pSlot[1];
// memset(pSlot, 0, nUnit * sizeof(uint32_t)) ;
pSlot[0]= pSlot[1]= 0;
m_lockFlist.Unlock() ;
return ssrAddr ;
}
m_lockFlist.Unlock() ;
top:
// No free slots so create another superblock
if (_hzGlobal_MT)
m_lockSbloc.Lock() ;
if (!m_pTopBlock || ((m_pTopBlock->m_Usage + nUnit) >&eq; SMAR_BLOC_SPACE))
{
// Assign any remaining free space on the highest block to the small freelist of the size
// Then create a new highest block
m_pTopBlock = pBloc = new _smarBloc() ;
pBloc->m_blkSelf = m_Super.Count() + 1;
pBloc->m_Usage = 0;
m_Super.Insert(pBloc->m_blkSelf, pBloc) ;
bNote = true ;
}
// Assign from the superblock free space
pSlot = m_pTopBlock->m_Space + m_pTopBlock->m_Usage ;
ssrAddr = ((m_pTopBlock->m_blkSelf) << 16)+m_pTopBlock->m_Usage ;
m_pTopBlock->m_Usage += nUnit ;
// memset(pSlot, 0, nUnit * sizeof(uint32_t)) ;
pSlot[0]= pSlot[1]= 0;
if (_hzGlobal_MT)
m_lockSbloc.Unlock() ;
if (bNote)
printf("SMAR %u: CREATED SUPERBLOCK %u at %p\n", m_nCode, pBloc->m_blkSelf, pBloc) ;
return ssrAddr ;
}