Skip to content

Commit

Permalink
LZMACompressor: Add more barriers.
Browse files Browse the repository at this point in the history
Again, not sure whether or not Windows on Arm's x86 emulator is weakly-ordered.
(In a native Arm64 build, they would be needed.)
  • Loading branch information
jordanrussell authored Nov 9, 2024
1 parent 0e3bd96 commit b445cf4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
14 changes: 11 additions & 3 deletions Projects/Src/Compression.LZMACompressor.pas
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,17 @@ function RingBufferInternalWriteOrRead(var Ring: TLZMACompressorRingBuffer;
if Bytes > SizeOf(Ring.Buf) - Offset then
Bytes := SizeOf(Ring.Buf) - Offset;

{ On a weakly-ordered CPU, the read of Count above must happen before
Buf content is read below (otherwise the content could be stale) }
MemoryBarrier;

if AWrite then begin
Move(P^, Ring.Buf[Offset], Bytes);
InterlockedExchangeAdd(Ring.Count, Bytes);
InterlockedExchangeAdd(Ring.Count, Bytes); { full barrier }
end
else begin
Move(Ring.Buf[Offset], P^, Bytes);
InterlockedExchangeAdd(Ring.Count, -Bytes);
InterlockedExchangeAdd(Ring.Count, -Bytes); { full barrier }
end;
if Offset + Bytes = SizeOf(Ring.Buf) then
Offset := 0
Expand Down Expand Up @@ -403,8 +407,12 @@ function RingBufferReadToCallback(var Ring: TLZMACompressorRingBuffer;
if Bytes > SizeOf(Ring.Buf) - Ring.ReaderOffset then
Bytes := SizeOf(Ring.Buf) - Ring.ReaderOffset;

{ On a weakly-ordered CPU, the read of Count above must happen before
Buf content is read below (otherwise the content could be stale) }
MemoryBarrier;

AWriteProc(Ring.Buf[Ring.ReaderOffset], Bytes);
InterlockedExchangeAdd(Ring.Count, -Bytes);
InterlockedExchangeAdd(Ring.Count, -Bytes); { full barrier }
if Ring.ReaderOffset + Bytes = SizeOf(Ring.Buf) then
Ring.ReaderOffset := 0
else
Expand Down
8 changes: 6 additions & 2 deletions Projects/Src/Compression.LZMACompressor/islzma/islzma_exe.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,16 @@ static Longint RingBufferInternalWriteOrRead(struct TLZMACompressorRingBuffer *R
Bytes = (Longint)sizeof(Ring->Buf) - *Offset;
}

/* On a weakly-ordered CPU, the read of Count above must happen before
Buf content is read below (otherwise the content could be stale) */
MemoryBarrier();

if (AWrite) {
memcpy(&Ring->Buf[*Offset], P, Bytes);
InterlockedExchangeAdd(&Ring->Count, Bytes);
InterlockedExchangeAdd(&Ring->Count, Bytes); /* full barrier */
} else {
memcpy(P, &Ring->Buf[*Offset], Bytes);
InterlockedExchangeAdd(&Ring->Count, -Bytes);
InterlockedExchangeAdd(&Ring->Count, -Bytes); /* full barrier */
}
if (*Offset + Bytes == sizeof(Ring->Buf)) {
*Offset = 0;
Expand Down

0 comments on commit b445cf4

Please sign in to comment.