Skip to content
Snippets Groups Projects
Commit a2267936 authored by John Hodge's avatar John Hodge
Browse files

Kernel - Fixed concurrency in the RingBuffer type

parent 0f822638
Branches
Tags
No related merge requests found
......@@ -21,45 +21,66 @@ tRingBuffer *RingBuffer_Create(size_t Space)
size_t RingBuffer_Read(void *Dest, tRingBuffer *Buffer, size_t Length)
{
if(Length > Buffer->Length) Length = Buffer->Length;
size_t tmpLen;
tmpLen = Buffer->Length; // Changed in Write, so cache it for our read
if(Length > tmpLen) Length = tmpLen;
if( Buffer->Start + Length > Buffer->Space )
{
int endData = Buffer->Space - Buffer->Start;
memcpy(Dest, &Buffer->Data[Buffer->Start], endData);
memcpy((Uint8*)Dest + endData, &Buffer->Data, Length - endData);
memcpy((Uint8*)Dest + endData, Buffer->Data, Length - endData);
}
else
{
memcpy(Dest, &Buffer->Data[Buffer->Start], Length);
}
// Lock then modify
SHORTLOCK( &Buffer->Lock );
Buffer->Start += Length;
if( Buffer->Start > Buffer->Space )
Buffer->Start -= Buffer->Space;
Buffer->Length -= Length;
SHORTREL( &Buffer->Lock );
return Length;
}
size_t RingBuffer_Write(tRingBuffer *Buffer, const void *Source, size_t Length)
{
size_t bufEnd = Buffer->Start + Buffer->Length;
size_t endSpace = Buffer->Space - bufEnd;
size_t bufEnd, endSpace;
size_t tmpLen, tmpStart;
// Cache Start and Length because _Read can change these
SHORTLOCK( &Buffer->Lock );
tmpStart = Buffer->Start;
tmpLen = Buffer->Length;
SHORTREL( &Buffer->Lock );
bufEnd = (Buffer->Start + Buffer->Length) % Buffer->Space;
endSpace = Buffer->Space - bufEnd;
// Force to bounds
if(Length > Buffer->Space - Buffer->Length)
Length = Buffer->Space - Buffer->Length;
if(Length > Buffer->Space - tmpLen) Length = Buffer->Space - tmpLen;
if(endSpace < Length)
{
memcpy( &Buffer->Data[bufEnd], Source, endSpace );
memcpy( Buffer->Data, (Uint8*)Source + endSpace, Length - endSpace );
Buffer->Length = Length - endSpace;
}
else
{
memcpy( &Buffer->Data[bufEnd], Source, Length );
Buffer->Length += Length;
}
// Lock then modify
SHORTLOCK( &Buffer->Lock );
Buffer->Length += Length;
SHORTREL( &Buffer->Lock );
return Length;
}
......@@ -14,6 +14,7 @@ typedef struct sRingBuffer
size_t Start; //!< Start of data in ring buffer
size_t Length; //!< Number of data bytes in buffer
size_t Space; //!< Allocated space in buffer
tShortSpinlock Lock; //!< Lock to prevent collisions
char Data[]; //!< Buffer
} tRingBuffer;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment