dotnet9x icon indicating copy to clipboard operation
dotnet9x copied to clipboard

InterlockedCompareExchange atomic implementation

Open friendlyanon opened this issue 10 months ago • 8 comments

This reimplementation of the function is obviously not atomic:

https://github.com/itsmattkc/dotnet9x/blob/ee01c8e767d406ec002b0903e716dede98d39ee1/wrappers/kernel32.c#L1777-L1789

However, this could be properly implemented in assembly via CMPXCHG if you require at least a 486 processor. Windows 95 requires at least a 386, so this would mean excluding only the oldest supported processor family for a correct implementation.

Detecting if the system is at least a 486 is also trivial, due to being able to set the AC bit in EFLAGS from user mode (https://en.wikipedia.org/wiki/FLAGS_register).

friendlyanon avatar Apr 14 '24 12:04 friendlyanon

You could add the check for 486 and then do the atomic operation if you have support. Otherwise fall-through into the original non-atomic one as a known/current limitation to 386 support.

cargoudel avatar Apr 14 '24 12:04 cargoudel

True, but that would be a correctness compromise.

friendlyanon avatar Apr 14 '24 14:04 friendlyanon

Otherwise fall-through into the original non-atomic one

Win98 used a driver for this when running on a 386

whindsaks avatar Apr 14 '24 22:04 whindsaks

According to Copilot, on a 386 processor, which does not support the CMPXCHG instruction, you could use the XCHG instruction in combination with a LOCK prefix to achieve similar functionality. The XCHG instruction exchanges the values of two operands, and the LOCK prefix ensures that the operation is atomic, preventing other processors from accessing the memory location during the operation

An example implementation using XCHG:

mov eax, [Comparand] ; Load Comparand into EAX register mov ebx, [Destination] ; Load Destination into EBX register mov ecx, [Exchange] ; Load Exchange into ECX register

cmp [ebx], eax ; Compare value at EBX with EAX jne done ; If not equal, jump to done lock xchg [ebx], ecx ; If equal, exchange values atomically

done:

See: https://www.felixcloutier.com/x86/xchg

What do you think?

andresvettori avatar Apr 18 '24 12:04 andresvettori

That isn't really atomic. Something could still end up changing the value of [ebx] before the lock xchg is performed.

iProgramMC avatar Apr 19 '24 14:04 iProgramMC

While the minimum requirements of Windows 95 is a 386 with 4MB RAM, it is not really a useful system and will start swapping as soon as you do anything. Even a 486 cannot play a mp3 in WinAmp v1 without skipping.

What I'm asking is, does anyone really care about pre-Pentium hardware as their .Net host? As a box to run DOS games in real mode on, sure. Running anything made after 1997? Not really?

whindsaks avatar May 07 '24 10:05 whindsaks

While the minimum requirements of Windows 95 is a 386 with 4MB RAM, it is not really a useful system and will start swapping as soon as you do anything. Even a 486 cannot play a mp3 in WinAmp v1 without skipping.

What I'm asking is, does anyone really care about pre-Pentium hardware as their .Net host? As a box to run DOS games in real mode on, sure. Running anything made after 1997? Not really?

Counterpoint: Does anyone really care about Windows 95 as their .Net host?

this project isn't about being practical, it's about pushing the limits.

easyaspi314 avatar Aug 17 '24 19:08 easyaspi314

this project isn't about being practical, it's about pushing the limits.

The problem is, supporting the 386 will make everyone slower because the code has to branch or do an indirect call.

whindsaks avatar Aug 17 '24 23:08 whindsaks