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
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
template <class T> class SecureStack { struct Entity { T val; Entity* next; Entity(T _val) : val(_val), next(0) { } ~Entity() { } }; Entity* Head; SecureStack(const SecureStack&) { }//forbitten void operator = (const SecureStack&) { }//forbitten public: class ReturnType { Entity* pointer; public: ReturnType(void) : pointer(0) { } ReturnType(Entity* e) : pointer(e) { } ReturnType(ReturnType& e) { pointer = e.pointer; e.pointer = 0; } ~ReturnType() { delete pointer; } bool operator = (ReturnType& e) { delete pointer; pointer = e.pointer; e.pointer = 0; return (pointer != NULL); } T& operator*(void) { return pointer->val; } T* operator ->(void) { return &pointer->val; } }; SecureStack(void) : Head(0) { } ~SecureStack() { while(Head) { Entity* p = Head; Head = Head->next; delete p; } } bool empty(void) const { return (Head == 0); } bool getAll(std::list<T> &list) { //wir ersetzen Head einfach gegen NULL und behalten Head #pragma warning( disable: 4312) #pragma warning( disable: 4311) Entity* oldH = (Entity*)InterlockedExchangePointer((void**)&Head, NULL); #pragma warning( default: 4312) #pragma warning( default: 4311) while(oldH) { list.push_front(oldH->val); Entity* h = oldH; oldH = oldH->next; delete h; } return true; } ReturnType pop(void) //not very fast { Entity* h = Head; if(!h) return NULL; //auch wenn h ungültig werden sollte, so gibt es keinen Segfault, //weil h->next ohne Zeigerverscheibung abläuft, //welche zum Absturz führen würden //wir tauschen Head und seinen Nachfolger einfach aus und behalten Head Entity* oldH = (Entity*)InterlockedCompareExchangePointer((void**)&Head, h->next, h); if(oldH != h) return 0; //da hat einer dazwischengefunkt else return oldH;//alles i.o. } void push(const T &val) { Entity* oldH, *h; Entity* n = new Entity(val); do { h = Head; n->next = h; oldH = (Entity*)InterlockedCompareExchangePointer((void**)&Head, n, h); }while(oldH != h); } }; |
Zitat
...Dabei ist mir aufgefallen, dass die Kommunikation über gelockte Listen zwar eine Option ist, aber doch teilweise massive Latenzprobleme herbeiführt...
Quellcode |
|
1 2 3 4 5 6 7 8 |
public void Pop() { ListNode newHead, origHead; do { // This does not work if we allow inserts in the list origHead = head; newHead = origHead.next; } while (CompareExchange<ListNode>( ref head, newHead, origHead) != origHead); } |
Werbeanzeige