Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Nox

Supermoderator

  • »Nox« ist der Autor dieses Themas

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

1

15.04.2008, 09:46

Potentieller Zeigerfehler?

Hi,

ich beschäftige mich im Moment mit lockfreien Implementationen von Stacks und Queues. Dabei brauche ich mal eine Informationen von den Leuten, die Ahnung von C/C++ -> asm haben.

C-/C++-Quelltext

1
2
3
Entity* h = Head;
if(!h) return NULL;
InterlockedCompareExchangePointer((void**)&Head, h->next, h);


Was passiert in diesem Fall, falls Head nach dem Holen der lokalen Kopie sich ändert und der Bereich auf den die lokale Kopie zeigt ungültig wird. Das InterlockedCompareExchangePointer wird auf jedenfall den Head nicht austauschen. Dass ist sicher gestellt. Allerdings wird doch das h->next vor dem Aufruf von InterlockedCompareExchangePointer "ausgeführt".
Meine Frage ist also:
kann das h->next einen Fehler verursachen, wenn h ungültig geworden ist, der daraus resultierende Pointer aber nicht genutzt wird?

(Begründung wäre nett, damit ich das nachvollziehen kann)
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

15.04.2008, 10:21

Re: Potentieller Zeigerfehler?

Zitat von »"Nox"«

kann das h->next einen Fehler verursachen, wenn h ungültig geworden ist, der daraus resultierende Pointer aber nicht genutzt wird?


Wenn h ungültig ist, dann führt das h->next auf jeden Fall zu einem Problem, da dann ein ungültiger pointer dereferenziert wird. Das Verhalten des Programmes in diesem Fall ist undefiniert. Was genau passiert hängt normal vom OS ab. Linux würde dich sofort mit einem segfault strafen. Windows sieht die Sache meiner Erfahrung nach etwas entspannter.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

3

15.04.2008, 12:01

Was für eine Operation soll das überhaupt sein?

Das Problem ist übrigens unter dem Namen ABA Problem bekannt. Lösungsansätze wäre z.B. eine Referenzenzählung der Zeiger (dafür benötigst du ein DCAS [cmpxchg16b] was tragischerweise noch recht selten Unterstützung findet) oder eine Softwarelösung über Hazard Pointer.
@D13_Dreinig

Nox

Supermoderator

  • »Nox« ist der Autor dieses Themas

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

15.04.2008, 17:35

ABA ist was ganz anderes. Das ABA Problem tritt nur auf, wenn man einen Pointer raus nimmt (A->B) und den Pointer danach wieder einfügt (B->A). Dieser Fall tritt bei mir nicht auf. Das Problem ist schlicht und ergreifend, dass ich nicht weiß ob Rear zu dem Zeitpunkt gültig ist oder nicht. Ich kann als (nach meinen Kenntnisstand) folgendes nicht machen:

C-/C++-Quelltext

1
InterlockedExchangePointer((void**)&Head, Head->next);

Also muss ich irgendwie sicher stellen, dass Head gültig ist. Noch Problematischer wird es, wenn ich sowas hier machen wollte:

C-/C++-Quelltext

1
2
3
r = Rear;
if(!r) return;
InterlockedExchangePointer((void**)&Rear->next, n, r);

Selbst der folgende Fall könnte eintreten, womit ich dann komplett aufgemissen bin:

C-/C++-Quelltext

1
2
3
if(Head)
//anderer Thread setzt Head auf NULL

InterlockedExchangePointer((void**)&Head, Head->next);//Head ist NULL=>NULL Pointer


Also insgesamt bin ich aufgeschmissen, da ich entweder ein cmpxchg mit einem Ungleich bräuchte, oder die Gewissheit, dass der "->" nur auseinanderfliegt, wenn ich versuche was an dem Speicherbereich zu ändern.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

15.04.2008, 17:41

Zitat von »"Nox"«

[...] oder die Gewissheit, dass der "->" nur auseinanderfliegt, wenn ich versuche was an dem Speicherbereich zu ändern.


leider gibt es diese gewissheit nicht. sobald du den nullzeiger oder einen ungültigen zeiger dereferenzierst, gibts undefiniertes verhalten...

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

15.04.2008, 17:45

Hazard Pointer helfen... :roll: Und ABA und ein Problem hängen durchaus zusammen...
@D13_Dreinig

Nox

Supermoderator

  • »Nox« ist der Autor dieses Themas

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

7

15.04.2008, 18:05

Zu Hazard Pointer:
Ich beziehe mich einfach nur auf die Quelle http://en.wikipedia.org/wiki/Hazard_pointer. Wenn das stimmt und ich es richtig verstanden habe, dann dürfte eine Statusvariable oder eine Critical Section eindeutig einfacher und wahrscheinlich auch leistungschonender sein.

Zu dem ABA Problem:
Natürlich kann ich Teile einer Variable missbrauchen, um darüber sicher zu stellen, dass die Var zwischenzeitlich nciht verändert wurde. Wie das allerdings mein Problem lösen soll, sehe ich im Moment noch nicht.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

15.04.2008, 18:07

Wieso? Du willst doch wissen ob der Zeiger sich geändert hat, nicht?
@D13_Dreinig

Nox

Supermoderator

  • »Nox« ist der Autor dieses Themas

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

9

15.04.2008, 18:13

Wenn der Bereich auf dem der Zeiger zeigt, gelöscht wird...was bringt mir dann die Information in der lokalen Kopie des Zeiger? Außerdem muss ich auch auf einem 64 bit System das ganze noch machen können und ich kenne noch kein cmpxchg was 128 bit frisst. Aber ich bin für jede Idee, wie ich an den Head->next Zeiger komme mehr als nur willkommen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

10

15.04.2008, 20:16

Zitat von »"Nox"«

Aber ich bin für jede Idee, wie ich an den Head->next Zeiger komme mehr als nur willkommen.


Anscheinend ja nicht... :roll: Du kannst ja zur Not das Löschverhalten selbst bestimmen... Mach ein Phoenixobjekt oder sonst was... Such dir was aus, so schwer wirds schon nicht sein.
@D13_Dreinig

Werbeanzeige