<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
oh. I already got it working. ok.<BR>
 <BR>
 <BR>
Atomic confuses me in a few ways.<BR>
 <BR>
 <BR>
I find it terribly confusing on Windows that there are separate compiler and memory fences.<BR>
I'd like there to be a very simple full fence that forces all reads/writes before it to finish before any reads/writes after it, both for the compiler and processor.<BR>
It makes no sense to me to allow the processor or compiler to reorder but not both.<BR>
 <BR>
 <BR>
What is weak cas?<BR>
Is that loadlocked/storecondition and the caller can loop?<BR>
 <BR>
 <BR>
Um. There is the Windows terminology InterlockedWhatever.<BR>
There is the gccc builtins.<BR>
Can we "sound" close to one of them?<BR>
Or is this based on some other widely known system?<BR>
 <BR>
 <BR>
And we don't care about older x86 processors like 386?486 I assume?<BR>
There seem to have been at least two leaps in functionality here.<BR>
Old Win32 operating systems provide very few interlocked functions.<BR>
They provide increment and decrement, that only return <0, 0, >0 of the new value.<BR>
And Exchange. (This is based on the Visual C++ 2.0 winbase.h)<BR>
All just on 32bit values.<BR>
 <BR>
Later on there is a much larger suite, Exchange, ExchangeAdd, Inc/Dec that return new value, all on 32 bit values.<BR>
 <BR>
And then later, stuff added for 16 values, bit operations, maybe 8 bit values, and, or, xor. I don't think this requires newer processors though.<BR>
 <BR>
And then also at some point InterlockedCompareExchange64 which requires the "newest" processors, but is still quite old.<BR>
>From this you can synthesize inc/dec/and/or/xor with loops and that is done with inline functions in winbase.h.<BR>
 <BR>
 <BR>
 - Jay<BR><BR> <BR>> From: hosking@cs.purdue.edu<BR>> Date: Fri, 18 Dec 2009 13:32:57 -0500<BR>> To: jay.krell@cornell.edu<BR>> CC: m3devel@elegosoft.com<BR>> Subject: Re: [M3devel] cas/casp?<BR>> <BR>> Hold your horses. I am in the middle of working up a more portable "Atomic" interface along the following lines. We can choose to implement with compiler intrinsics like Word/LongWord (if available), but otherwise will provide a call interface. I envision instantiating for ADDRESS, CHAR, and Word.T. This means CAS/CASP will go away.<BR>> <BR>> GENERIC INTERFACE Atomic(Rep);<BR>> <BR>> IMPORT RTMachine;<BR>> <BR>> TYPE T = Rep.T;<BR>> <BR>> PROCEDURE MemoryFence();<BR>> (* Guarantees explicit memory ordering for otherwise unordered atomics, and<BR>> for other memory references wrt atomics. Not useful for ordering<BR>> ordinary memory references, since those may not race and, if they don't<BR>> race, always appear to be ordered. *)<BR>> <BR>> PROCEDURE CompilerFence();<BR>> (* Ensures that prior memory operations appear in the instruction stream<BR>> before subsequent ones, i.e. the compiler is not allowed to reorder<BR>> around this. This really has only implementation-defined semantics, but<BR>> it seems to be useful in ensuring ordering with respect to signal<BR>> handlers and the like. *)<BR>> <BR>> PROCEDURE Store(VAR var: T; val: T); (* No ordering guarantees. *)<BR>> PROCEDURE StoreRelease(VAR var: T; val: T);<BR>> <BR>> PROCEDURE Load(READONLY var: T): T; (* No ordering guarantees. *)<BR>> PROCEDURE LoadAcquire(READONLY var: T): T;<BR>> <BR>> TYPE Order = { Raw, Acquire, Release, Ordered };<BR>> (* "Raw" ==> This operation is unordered, and may become visible to other<BR>> threads in an order that is constrained only by ordering constraints<BR>> on other operations.<BR>> <BR>> "Release" ==> All prior memory operations (including ordinary<BR>> assignments) become visible to a an acquire operation on the same<BR>> object that sees the resulting value.<BR>> <BR>> "Acquire" ==> See above.<BR>> <BR>> "Ordered" ==> Both acquire and release ordering properties.*)<BR>> <BR>> CONST HasCas = RTMachine.HasCas;<BR>> CONST HasWaitFreeCas = RTMachine.HasWaitFreeCas;<BR>> PROCEDURE Cas(VAR var: T; old, new: T; order := Ordered): T;<BR>> (* Most architectures provide a way to return the old value. On those that<BR>> do not, it can be emulated with an additional load, at the expense of<BR>> wait-freedom or spurious failure. *)<BR>> <BR>> CONST HasWeakCas = RTMachine.HasWeakCas;<BR>> PROCEDURE WeakCas(VAR var: T; old, new: T; order := Ordered): T;<BR>> (* Similar to "Cas", but may fail spuriously, and must be wait-free, if<BR>> provided. *)<BR>> <BR>> CONST HasFetchAdd = RTMachine.HasFetchAdd;<BR>> PROCEDURE FetchAdd(VAR var; incr: T; order := Raw): T;<BR>> <BR>> CONST HasFetchOr = RTMachine.HasFetchOr;<BR>> PROCEDURE FetchOr(VAR var; mask: T; order := Raw): T;<BR>> <BR>> CONST HasFetchAnd = RTMachine.HasFetchAnd;<BR>> PROCEDURE FetchOr(VAR var; mask: T; order := Raw): T;<BR>> <BR>> END Atomic.<BR>> <BR>> <BR>> On 18 Dec 2009, at 13:04, Jay K wrote:<BR>> <BR>> > Tony is this right?<BR>> > <BR>> > <BR>> > conceptually:<BR>> > <BR>> > <BR>> > result := CAS(VAR destination, compare, exchange)<BR>> > <BR>> > <BR>> > old := destination<BR>> > if old := compare then<BR>> > destination = exchange<BR>> > return old<BR>> > <BR>> > <BR>> > bool result := CASP(VAR destination, compare, exchange)<BR>> > P for predicate aka returning bool<BR>> > <BR>> > <BR>> > old := destination<BR>> > if old = compare then<BR>> > destination := exchange<BR>> > return true<BR>> > return false<BR>> > <BR>> > <BR>> > I'm pretty sure it is.<BR>> > <BR>> > <BR>> > I'll have this for 16 bit and 32 bit values shortly, for now requiring<BR>> > a recent Microsoft compiler and it generates function calls.<BR>> > But inlining should be easy enough.<BR>> > And then 8bit and 64bit.<BR>> > <BR>> > <BR>> > Also this will probably not work on 386 or 486 but require Pentium or somesuch.<BR>> > I don't know when various instructions were introduced but I know<BR>> > 386 is much poorer here than modern processors.<BR>> > <BR>> > <BR>> > I assume only support int8, uint8, int16, uint16, int32, uint32, int64, uint64, size_t, ptrdiff_t<BR>> > and not e.g. floating point.<BR>> > <BR>> > <BR>> > - Jay<BR>> <BR>                                          </body>
</html>