[Mono-devel-list] [PATCH] .Net 2.0 System.Threading.Interlocked, tests and internal improvements

Ben Maurer bmaurer at ximian.com
Tue Oct 12 08:52:21 EDT 2004

> Here we run into problems with the patch.  io-layer has to follow the
> Windows API, because it's used as a replacement for the native Windows
> functions on non-Windows builds.  Your patch will cause the Windows
> build of mono to break.
> You can see the Interlocked API list here:
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/synchronization_functions.asp

Here we are going to run into more problems. Many of the functions we need
will only be defined for newer versions of windows. eg.
InterlockedCompareExchange64 is only defined for Windows 2k3 server. Even
XP does not have it.

So, we are probably going to need to do much of this outside of io-layer,
since I assume we want to keep support for XP and 2000 (and maybe NT 4).

This has another advantage. We can implement stuff like
InterlockedIncrementBlind. We can do:

lock; add [value], delta

__builtin_is_constant_p can be used so that we can replace this with inc
when delta is 1, etc. (btw, on a pentium 4, when optimizing for speed, gcc
will use add eax, 1. IIRC, the intel docs say this is faster. maybe totte
can confirm this).

There are a few other functions that might prove to be useful.
InterlockedOr, InterlockedAnd, InterlockedXor could be used in a few
places (eg, look at Thread.cs there is a lock in there that could be
replaced with interlocked functions).

>> - On amd64, I believe that cmov/fcmov JIT optimizations were disabled
>> due to a coding mistake, so I enabled them while moving the cpuid code
>>  to a central place. This may not be the case.
> Be aware that some 686s don't have cmov, it's an optional instruction.
> For example, the VIA C3:
> vendor_id       : CentaurHauls
> cpu family      : 6
> model           : 7
> model name      : VIA Ezra
> flags           : fpu de tsc msr cx8 mtrr pge mmx 3dnow
> Linux ceasterware 2.6.5-7.108-default #1 Wed Aug 25 13:34:40 UTC 2004
> i686 i686 i386 GNU/Linux

Interesting. Doesn't gcc use cmov when you say -march=i686?

BTW, one other suggestion, maybe this is better for another patch. The
Interlocked functions should be jit intrinsics, like String.Length is.
There are a few hacks you can do nicely with this:

1) remove lock; on uni-proc boxes
Using lock makes the instructions much, much slower. On smp boxes it is
needed for correctness, but not on u-p boxes.

2) We can replace InterlockedIncrement with IncrementBlind, etc
In the jit if you have:

pop (interlocked_increment ([foo]))

You could emit

lock; inc [foo]

Which is much faster than the xadd version of the same code. Similar
tricks can be done with ExchangeAdd.

-- Ben

More information about the Mono-devel-list mailing list