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
No related merge requests found
...@@ -21,45 +21,66 @@ tRingBuffer *RingBuffer_Create(size_t Space) ...@@ -21,45 +21,66 @@ tRingBuffer *RingBuffer_Create(size_t Space)
size_t RingBuffer_Read(void *Dest, tRingBuffer *Buffer, size_t Length) 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 ) if( Buffer->Start + Length > Buffer->Space )
{ {
int endData = Buffer->Space - Buffer->Start; int endData = Buffer->Space - Buffer->Start;
memcpy(Dest, &Buffer->Data[Buffer->Start], endData); memcpy(Dest, &Buffer->Data[Buffer->Start], endData);
memcpy((Uint8*)Dest + endData, &Buffer->Data, Length - endData); memcpy((Uint8*)Dest + endData, Buffer->Data, Length - endData);
} }
else else
{ {
memcpy(Dest, &Buffer->Data[Buffer->Start], Length); memcpy(Dest, &Buffer->Data[Buffer->Start], Length);
} }
// Lock then modify
SHORTLOCK( &Buffer->Lock );
Buffer->Start += Length; Buffer->Start += Length;
if( Buffer->Start > Buffer->Space ) if( Buffer->Start > Buffer->Space )
Buffer->Start -= Buffer->Space; Buffer->Start -= Buffer->Space;
Buffer->Length -= Length; Buffer->Length -= Length;
SHORTREL( &Buffer->Lock );
return Length; return Length;
} }
size_t RingBuffer_Write(tRingBuffer *Buffer, const void *Source, size_t Length) size_t RingBuffer_Write(tRingBuffer *Buffer, const void *Source, size_t Length)
{ {
size_t bufEnd = Buffer->Start + Buffer->Length; size_t bufEnd, endSpace;
size_t endSpace = Buffer->Space - bufEnd; 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 // Force to bounds
if(Length > Buffer->Space - Buffer->Length) if(Length > Buffer->Space - tmpLen) Length = Buffer->Space - tmpLen;
Length = Buffer->Space - Buffer->Length;
if(endSpace < Length) if(endSpace < Length)
{ {
memcpy( &Buffer->Data[bufEnd], Source, endSpace ); memcpy( &Buffer->Data[bufEnd], Source, endSpace );
memcpy( Buffer->Data, (Uint8*)Source + endSpace, Length - endSpace ); memcpy( Buffer->Data, (Uint8*)Source + endSpace, Length - endSpace );
Buffer->Length = Length - endSpace;
} }
else else
{ {
memcpy( &Buffer->Data[bufEnd], Source, Length ); memcpy( &Buffer->Data[bufEnd], Source, Length );
Buffer->Length += Length;
} }
// Lock then modify
SHORTLOCK( &Buffer->Lock );
Buffer->Length += Length;
SHORTREL( &Buffer->Lock );
return Length; return Length;
} }
...@@ -14,6 +14,7 @@ typedef struct sRingBuffer ...@@ -14,6 +14,7 @@ typedef struct sRingBuffer
size_t Start; //!< Start of data in ring buffer size_t Start; //!< Start of data in ring buffer
size_t Length; //!< Number of data bytes in buffer size_t Length; //!< Number of data bytes in buffer
size_t Space; //!< Allocated space in buffer size_t Space; //!< Allocated space in buffer
tShortSpinlock Lock; //!< Lock to prevent collisions
char Data[]; //!< Buffer char Data[]; //!< Buffer
} tRingBuffer; } 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