Return of spinoza1111

K

Keith Thompson

Chris M. Thomasson said:
I need to be able to spinoza mutate a reference to an object along
with an integer. In C, the data-structure would look like this for a
32-bit system: [snip]
in a 64-bit system it would look like: [snip]
In Java this can be accomplished via `AtomicStampedReference': [snip]
Is there an analog of `AtomicStampedReference' in C#? Please try and
bear with be here because I am certainly no expert in C#!


thanks for you help spinoza; I appreciate it. If I can pull this off
in C#, I will be happy!
[snip]

Chris:

If you want to discuss C# or Java, please take it to a forum that
discusses those languages. If you want to discuss "spinoza" (is that
a language?), you might try comp.lang.misc or e-mail; comp.programming
might be appropriate as well, but comp.lang.c is not.
 
C

Chris M. Thomasson

Chris M. Thomasson said:
I need to be able to spinoza mutate a reference to an object along with an
integer. In C, the data-structure would look like this for a 32-bit
system:


struct anchor64 {
void* ptr; /* assume void* is 32-bits */
int32_t count;
};


static struct anchor64 g_anchor64 = { NULL };


Now, I can use DWCAS (e.g., CMPXCHG8B on IA-32) to atomically mutate
`g_anchor64'.
[...]


Well, here is what I came up with:

http://pastebin.com/m4ac170c


It seems we have liftoff spinoza!


:^D
 
C

Chris M. Thomasson

Chris M. Thomasson said:
Chris M. Thomasson said:
I need to be able to spinoza mutate a reference to an object along with
an integer. In C, the data-structure would look like this for a 32-bit
system:


struct anchor64 {
void* ptr; /* assume void* is 32-bits */
int32_t count;
};


static struct anchor64 g_anchor64 = { NULL };


Now, I can use DWCAS (e.g., CMPXCHG8B on IA-32) to atomically mutate
`g_anchor64'.
[...]


Well, here is what I came up with:

http://pastebin.com/m4ac170c


It seems we have liftoff spinoza!

DAMN IT!!!!!!! ARGH. I think I spoke too soon! Something is NOT working
here. This is an example:


http://pastebin.com/m16a32c47


This simple contrived example was designed to force the DWCAS to fail by
explicitly setting the counter portion of the comparand to 5, while the
target's counter was 1. However, it erroneously succeeded anyway. The DWCAS
should have failed. I must be missing something here.



I have to go right now, but I will post this query over on a C# newsgroup. I
will post a link to my question here, so that any followers can continue
reading the discussion over there.


thank you for you patience.
 
S

spinoza1111

Chris M. Thomasson said:
with an integer. In C, the data-structure would look like this for a
32-bit system: [snip]
in a 64-bit system it would look like: [snip]
In Java this can be accomplished via `AtomicStampedReference': [snip]
Is there an analog of `AtomicStampedReference' in C#? Please try and
bear with be here because I am certainly no expert in C#!
thanks for you help spinoza; I appreciate it. If I can pull this off
in C#, I will be happy!

[snip]

Chris:

If you want to discuss C# or Java, please take it to a forum that
discusses those languages.  If you want to discuss "spinoza" (is that
a language?), you might try comp.lang.misc or e-mail; comp.programming
might be appropriate as well, but comp.lang.c is not.

An actual discussion has started without disruption. The question is
whether the safer language C Sharp can replace C, so Thomasson's
discussion is on-topic. What offends you is that he came in here to
mock me but was mocked in a creative fashion with a limerick you
couldn't have written, so we had a laugh and simmered down...so now
you're coming in with a topic canard and flame because you have a
vested interest in this ng being a haven for incompetent bullies.

I can't follow all his technology but I am trying, so I'll thank you
to desist.
 
S

spinoza1111

Chris M. Thomasson said:
I can Interchange a 64 bit Long as an atomic operation in the current
free release of C Sharp "express":
System.Threading.Interlocked.Exchange(ref lngValue, lngValue2);
Is this what you mean?
I can do this with double precision values in addition to Longs.
Is this what you mean?
I can even do this with reference objects using generics.
Is this what you mean?
I need to be able to spinoza mutate a reference to an object along with
an integer. In C, the data-structure would look like this for a 32-bit
system:
struct anchor64 {
 void* ptr; /* assume void* is 32-bits */
 int32_t count;
};
static struct anchor64 g_anchor64 = { NULL };
Now, I can use DWCAS (e.g., CMPXCHG8B on IA-32) to atomically mutate
`g_anchor64'. [...]

Well, here is what I came up with:

It seems we have liftoff spinoza!

DAMN IT!!!!!!! ARGH. I think I spoke too soon! Something is NOT working
here. This is an example:

http://pastebin.com/m16a32c47

This simple contrived example was designed to force the DWCAS to fail by
explicitly setting the counter portion of the comparand to 5, while the
target's counter was 1. However, it erroneously succeeded anyway. The DWCAS
should have failed. I must be missing something here.

I have to go right now, but I will post this query over on a C# newsgroup.. I
will post a link to my question here, so that any followers can continue
reading the discussion over there.

thank you for you patience.- Hide quoted text -

No problem, but you're doing all the significant work here. I more or
less blindly identified a feature I don't use all that much but seemed
to be what you wanted.
 
C

Chris M. Thomasson

No problem,

thank you! :^D



t you're doing all the significant work here. I more or
less blindly identified a feature I don't use all that much but seemed
to be what you wanted.

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!



:^)
 
L

luserXtrog

Whoa, cowboy. You're saying that to oppose bigotry in a general form,
an inability to relate and a tendency to exclude, is bigotry.

No. I said what I said. I did not say what you said.
You did not say what I said. You said what you said.

But that would mean that one could never object to bigotry. How nice
for bigots. They only have to start whining about "reverse
discrimination".

False premise implies dubious conclusion. Big surprise!

A unilateral prejudice against bigotry is itself bigotry;
but (IMHO) it is the least destructive kind, and the only
alternative is that strange little philosophy described
by Jeshua ben Miriam which few are capable of following
in earnest.
 
S

spinoza1111

No. I said what I said. I did not say what you said.
You did not say what I said. You said what you said.


False premise implies dubious conclusion. Big surprise!

A unilateral prejudice against bigotry is itself bigotry;
but (IMHO) it is the least destructive kind, and the only
alternative is that strange little philosophy described
by Jeshua ben Miriam which few are capable of following
in earnest.

The nice thing about the philosophies of Jesus, Ghandi, and Dr. King
is that they don't have to be followed "in earnest". Following them
just a little and for shits and giggles heals the world, whereas to
follow the silly philosophy that they are just a charming species of
bigot takes too much work and usually leads to the war of all against
all.

- Show quoted text -- Hide quoted text -

- Show quoted text -
 
S

spinoza1111

No problem,

thank you!   :^D
t you're doing all the significant work here. I more or
less blindly identified a feature I don't use all that much but seemed
to be what you wanted.

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!

:^)

I am working with your code in C# Express right now. I am surprised
that I can be of help since I now work full time as a K-12 teacher,
having left the field after publishing Build Your Own .Net Language
and Compiler (Apress 2004) owing to disgust with programmers here. But
this is an interesting and challenging project. Thanks.
 
S

spinoza1111

No problem,

thank you!   :^D
t you're doing all the significant work here. I more or
less blindly identified a feature I don't use all that much but seemed
to be what you wanted.

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!

:^)

Preliminary answer:

http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange.aspx

CompareExchange<(Of <(T>)>)(T%, T, T) Compares two instances of the
specified reference type T for equality and, if they are equal,
replaces one of them.

But your cmp is a NEW anchor. The types are "equal" only if their
names refer to the same instance. So, the compare never occurs.

I have some kids coming for the next class, will continue to
research...
 
S

spinoza1111

No problem,

thank you!   :^D
t you're doing all the significant work here. I more or
less blindly identified a feature I don't use all that much but seemed
to be what you wanted.

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".
 
S

spinoza1111

"spinoza1111" <[email protected]> wrote in message
[...]
thank you for you patience.- Hide quoted text -
No problem,
thank you!   :^D
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 -

We seem to be in comp.programming and not comp.lang.c. If you made
that change Chris, cool. If anyone else did, not cool. This discussion
is as much about C undt seinem grossen deficiencies, undt ihren
replaceablity by C Sharp EVEN FOR DER LOW LEVEL SYSTEM
PROGRAMMERUNGEN, as it is about C Sharp. Keith Thompson, if it was
you, quit screwing around.

My brother in law is a hardcore C guy and has a very low opinion
of .Net. For me it works fine and the full-featured Express editions
of C Sharp, VB and C++ are free. To me, C code is coyote ugly whereas
the above C Sharp code seems rather straightforward. It means you can
do some systems programming in C Sharp, if not all. But I can't
convince my brother in law of that.

Even high level languages that sharply depart from Von Neumann such as
rexx and lisp can be compiled down to straight binary with no runtime.
Rexx has one data type (the string), unlimited precision decimal
arithmetic, and an associative memory in which arrays and other data
structure can be indexed with strings. With a smart-enough compiler
such as exists for Rexx, you could write an OS in Rexx (I wrote a
parser generator in Rexx in 1991).

It might be "slow", but the Princeton economist Paul Krugman points
out in today's International Herald Tribune that using superfast
computers with blazingly fast software to make trades faster than any
other kid on Wall Street (sometimes canceling trades at the last
minute in a fraudulent but legal way) produces NOTHING of value for
society. I'm tired of faster and faster computers and every year
dumber and more vicious people, and I'd hasard there's a relationship.

Perhaps people who like fast computing should have gone into
electrical engineering and computer architecture, there to figure out
how to support languages in which the goal is truth-as-correctness,
not idiot ape speed for Chrissake. "Speed" of calculation is basically
a metaphor. CORRECTNESS is not.
 
L

luserXtrog

The nice thing about the philosophies of Jesus, Ghandi, and Dr. King
is that they don't have to be followed "in earnest". Following them
just a little and for shits and giggles heals the world, whereas to
follow the silly philosophy that they are just a charming species of
bigot takes too much work and usually leads to the war of all against
all.

mu. phoo, too.
"homo" schmoe know' no mo'.
when, then, friend,
will you make sense?

 
C

Chris M. Thomasson

That seems to this relative layperson pretty silly. It festishizes a
"cache boundary" which is not a law of nature, but the result of
another developer wanting, for a good reason or bad, to do bit shifts
rather than addition or subtraction...I think.
It's absurd to reason from such a specific need to the conclusion that
C is great.

I have no time to make full response, but padding critical portions of your
shared data-structures up to the size of a L2 cache-line, and strictly
aligning them on L2 cache-line boundaries can eliminate so-called
false-sharing which can totally destroy the performance, and any chance of
scalability of a multi-threaded application.

In C, I can actually hack something together. Unfortunately, not really
possible in managed code without resorting to the use of unmanaged
libraries...

[...]
 
S

spinoza1111

mu. phoo, too.
"homo" schmoe know' no mo'.
when, then, friend,
will you make sense?

There is a frog, named luserxtrog
With the poetic ability of an untrained dog
Words of wisdom words of sense
To him are meaningless, now and hence
To the fool wisdom is not cool:
Idiocracy is his general rule.
Good style is to him stuck up,
And all he'll say, is,
"You talk like a fag, and your shit's all fucked up"
Such fool's approval stings, and their honor stains
They shall be washed down the sewer in the coming rains.

- Show quoted text -- Hide quoted text -

- Show quoted text -
 
S

spinoza1111

I have no time to make full response, but padding critical portions of your
shared data-structures up to the size of a L2 cache-line, and strictly
aligning them on L2 cache-line boundaries can eliminate so-called
false-sharing which can totally destroy the performance, and any chance of
scalability of a multi-threaded application.

In C, I can actually hack something together. Unfortunately, not really
possible in managed code without resorting to the use of unmanaged
libraries...

I do not know why it is necessary to pad structures up to the size of
an L2 cache line, nor why it is necessary to align them on boundaries.
To me this is a job for the runtime. But I agree that in most systems
this might mean a thrilling return to C and MASM.

However, C Sharp provides for simulating C unions by allowing
directives that back member origins back up to the start of the
previous structure member in a way which hides member lengths. It may
also provide a directive to force the size of a structure to some
convenient power of two which in general is what things like fast
caches want, right?

Alternatively, the C sharp programmer could measure the size of the
data structure (easy when it contains only data, very very hard when
it contains code) and add extra dummy variables to pad. Or, the
compiler could do this. It can also align to powers of two boundaries.

This can be done without exiting managed code. In fact, I had to
modify the SL-1 compiler at Bell Northern Research from a 16 bit to a
24 bit target, the large scale Northern Telecom switch SL-1/XT for big
PBX applications, and I got wrapped around the axle making sure the
compiler generated object code starting at power of two boundaries. We
wanted the switch to be 32 bits but the mechanical engineers had said
that they could not design rack mounts for 32 bit hardware of the
time.

The problem is that additional infrastructure has to be written to
enable the high-level managed to do low level stuff, and management
wants to see programmers working, assholes and elbows, on the so-
called, and fetishized, "business problem". Therefore C and MASM are
used and the mess gets worse.
[...]- Hide quoted text -

- Show quoted text -
 
S

spinoza1111

mu. phoo, too.
"homo" schmoe know' no mo'.
when, then, friend,
will you make sense?

When you trouble to learn the deep relation of programming to general
culture, technology being a subclass of culture and not independent,
cowboy.

The fact is, bubba, that the interesting questions here apart from
showing that we can do what Chris wants are philosophical. In ordinary
speech we make the mistake of assuming that two different things can
be the same. We are especially prone to do this because today, the
Crap We Buy At The Store consists of products made on assembly lines
to be "the same" as any other product with the same name, although
maintaining the illusion that a Ford car carefully maintained by Joe
Straight Arrow is the "same" or interchangeable with the "same" make/
model/year transformed into a beater or clunker by Idiot Boy is hard
to say the least.

Thus in OO coding we have the illusion that unlike objects can be
compared, and that objects of the same class can by default, and
without coding, be compared. Because in capitalist society all things
are thought to be fungible using the money nexus, we think it's easy
to "clone", but it's not, and this is a good thing.

- Show quoted text -- Hide quoted text -

- Show quoted text -
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top