"spinoza1111" <
[email protected]> wrote in message
[...]
thank you for you patience.- Hide quoted text -
No problem,
Trust me spinoza, you hit the nail directly on the head. Anyway, here is
full self-contained compliable example code in C and IA-32 asm (MSVC 6.0
and higher) that I am trying to accomplish/mimic in C#:
___________________________________________________________________________
#include <stdio.h>
__declspec(naked) int
IA32_DWCAS(
void volatile* const _pthis,
void* const pcmp,
void const* const pxhcg
) {
_asm {
PUSH ESI
PUSH EBX
MOV ESI, [ESP + 16]
MOV EAX, [ESI]
MOV EDX, [ESI + 4]
MOV ESI, [ESP + 20]
MOV EBX, [ESI]
MOV ECX, [ESI + 4]
MOV ESI, [ESP + 12]
LOCK CMPXCHG8B QWORD PTR [ESI]
JNE x86_DWCAS_failed
MOV EAX, 1
POP EBX
POP ESI
RET
x86_DWCAS_failed:
MOV ESI, [ESP + 16]
MOV [ESI], EAX
MOV [ESI + 4], EDX
MOV EAX, 0
POP EBX
POP ESI
RET
}
struct DWCAS_Anchor {
void* ptr;
unsigned __int32 counter;
static struct DWCAS_Anchor g_anchor = { NULL };
int main(void) {
struct DWCAS_Anchor cmp = g_anchor;
struct DWCAS_Anchor xchg = { NULL, 666 };
printf("Before DWCAS:\nDWCAS_Anchor.ptr = %p\nDWCAS_Anchor.counter ==
%lu\n\n",
g_anchor.ptr, g_anchor.counter);
if (IA32_DWCAS(&g_anchor, &cmp, &xchg)) {
printf("After DWCAS:\nDWCAS_Anchor.ptr = %p\nDWCAS_Anchor.counter ==
%lu\n\n",
g_anchor.ptr, g_anchor.counter);
}
cmp.counter = 666;
xchg.counter = 555;
if (IA32_DWCAS(&g_anchor, &cmp, &xchg)) {
printf("After DWCAS:\nDWCAS_Anchor.ptr = %p\nDWCAS_Anchor.counter ==
%lu\n\n",
g_anchor.ptr, g_anchor.counter);
}
cmp.counter = 123;
xchg.counter = 999;
if (IA32_DWCAS(&g_anchor, &cmp, &xchg)) {
printf("After DWCAS:\nDWCAS_Anchor.ptr = %p\nDWCAS_Anchor.counter ==
%lu\n\n",
g_anchor.ptr, g_anchor.counter);
} else {
printf("After DWCAS FAILED:\nDWCAS_Anchor.ptr = %p\nDWCAS_Anchor.counter
== %lu\n\n",
g_anchor.ptr, g_anchor.counter);
}
return 0;}
If you can give me any hints pointers, I will be absolutely grateful.
BTW, thank you for your valuable time. I am glad we can get along now. I
learn a lesson from you: DO NOT JUMP TO CONCLUSIONS LIKE A STUPID MORON!
Is the code at the end of this post what you wanted? I changed cmp to
set it to target so that the equality holds. It is not possible for
CompareExchange to determine whether two objects are internally
identical in all particulars, since equality-of-objects is only
predefined for value objects and strings (and in the case of strings,
there are different theories, such as case sensitivity versus case
insensitivity, as to what constitutes inequality).
class application
{
class anchor<T>
{
public T m_ptr;
public long m_counter;
public anchor(T foo, long counter)
{
m_ptr = foo;
m_counter = counter;
}
};
static bool DWCAS<T>(ref anchor<T> dest, ref anchor<T> cmp,
anchor<T> xchg)
{
anchor<T> ret = System.Threading.Interlocked.CompareExchange
(ref dest, xchg, cmp);
if (ret.m_ptr.Equals(cmp.m_ptr) && ret.m_counter ==
cmp.m_counter) return true;
cmp = ret;
return false;
}
static void Main(string[] args)
{
anchor<string> target = new anchor<string>("Hello", 1);
anchor<string> xchg = new anchor<string>("Goodbye", 2);
anchor<string> cmp = target; // new anchor<string>
(target.m_ptr, 1); ***** CHANGED ******
System.Console.WriteLine("Before DWCAS:\ntarget.m_ptr == " +
target.m_ptr +
"\ntarget.m_counter == " + target.m_counter + "\n");
if (DWCAS(ref target, ref cmp, xchg))
{
System.Console.WriteLine("After DWCAS:\ntarget.m_ptr == "
+ target.m_ptr +
"\ntarget.m_counter == " + target.m_counter + "\n");
}
System.Console.WriteLine("\n\nPress <ENTER> to exit...");
System.Console.ReadLine();
}
};
RESULTS
Before DWCAS:
target.m_ptr == Hello
target.m_counter == 1
After DWCAS:
target.m_ptr == Goodbye
target.m_counter == 2
Press <ENTER> to exit...
Thus the only meaningful "equality" of objects is Leibnizian and as
such reminiscent of the philosopher Leibniz' "identity of
indiscernibles". Leibniz' ontology, if memory serves, consisted of
monads (objects) all distinct because no matter how closely they
match, they had different locations in space and time (raum undt
zeit). Thus in software, two objects are only the same if they are the
same, viz., two names of the same object return identical "space time
coordinates" (addresses in von Neumann space).
Interestingly however, this raises a problem for Leibniz if not
software. NAMES cannot themselves be monads because NAMES do not
occupy Leibnizian space and time. Interestingly computer storage
models the philosophical problem, because at runtime absent a
debugger, the NAMES of objects go away and have no location in von
Neumann space and time. Leibniz may have failed, in his ontology, to
account for language if he intended monads to explain everything.
But I digress. Or, as Dan Appleman wrote on my manuscript during his
dev edit of Build Your Own .Net Language and Compiler, "yeah, you
digress".- Hide quoted text -
- Show quoted text -