Excerpt from HTrace.cpp
bool AddToTraceBuffer
(
const char * p_String,
int p_Len
)
{
if(!s_Impl.m_BufferPointers.m_GlobalHeader)
return false;
unsigned long l_TextAreaSize =
s_Impl.m_BufferPointers.m_TextAreaSize;
if(!l_TextAreaSize)
return false;
unsigned long * l_BytesWritten = &s_Impl.
m_BufferPointers.m_GlobalFooter->m_NumBytesWritten;
if(s_Impl.m_BufferPointers.m_GlobalFooter->m_Frozen)
return false;
char * l_TextArea = s_Impl.m_BufferPointers.m_TextArea;
if((unsigned long)p_Len > l_TextAreaSize)
p_Len = l_TextAreaSize;
//To ensure thread safety, we access the m_WriteTo
//variable only from the single atomic operation
unsigned long l_WriteAt = InterlockedExchangeAdd
((long*)l_BytesWritten,p_Len);
if(l_WriteAt + p_Len > s_Impl.m_BufferPointers.
m_GlobalFooter->m_StopAfterThreshold)
{
s_Impl.m_BufferPointers.m_GlobalFooter->m_Frozen = 1;
return false;
}
//Now we reserved a space in the buffer,which other threads
//will not touch, unless the buffer is filled too fast. In
//that case we will have meaningless garbage in the buffer.
//Wrap around (circular buffer):
l_WriteAt %= l_TextAreaSize;
if(l_WriteAt + p_Len <= l_TextAreaSize)
{
memcpy(l_TextArea + l_WriteAt, p_String, p_Len);
}
else
{
unsigned long l_WriteAtTheTail =
l_TextAreaSize - l_WriteAt;
memcpy(l_TextArea + l_WriteAt, p_String,
l_WriteAtTheTail);
unsigned long l_WriteAtTheBeginning =
p_Len -l_WriteAtTheTail;
memcpy(l_TextArea, p_String + l_WriteAtTheTail,
l_WriteAtTheBeginning);
}
return true;
}//bool AddToTraceBuffer
End of Listing