Esempio n. 1
0
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Tries to extract the top object of the stack.
    // If the stack is empty, the method returns nullptr.
    T* Pop() {
        T* node;
        int waitCount = 0; // Used for back off.
        time_ = ThreadUtils::GetSystemTime();

        while(true) {
            HeadType oldHead = Memory::ReadValue(&head_);
            node = oldHead.GetFirst();

            if(node == nullptr) {
                return nullptr; // The stack is empty;
            }

            // Is 'head' still the same?
            if(oldHead == Memory::ReadValue(&head_)) {
                HeadType newHead = HeadType(oldHead.GetCount() - 1, node->Next);

                if(CompareExchange(oldHead, newHead)) {
                    return node; // The head was successfully updated.
                }
            }

            if((++waitCount % 50) == 0) {
                // Give threads with a lower priority a chance to run.
                ThreadUtils::SwitchToThread();
            }
            else {
                // Backoff.
                for(int i = 0; i < waitCount; i++) {
                    ThreadUtils::Wait();
                }
            }
        }
    }
U32 Interlocked::Add(U32 * addr, U32 value)
{
	volatile U32 addrValue,sum;
	do
	{
		addrValue = *addr;

		sum = addrValue + value;

		if(CompareExchange(addr,sum,addrValue) == addrValue)
			return sum;

	}while(true);
}
Esempio n. 3
0
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Tries to insert an object in the stack.
    // If the maximum number of objects is reached, the object 
    // isn't inserted anymore and the method returns the address of the object.
    // If the object could be inserted, the method returns nullptr.
    T* Push(T* node) {
        int waitCount = 0; // Used for back off.
        time_ = ThreadUtils::GetSystemTime();

        while(true) {
            HeadType oldHead = Memory::ReadValue(&head_);

            if(oldHead.GetCount() >= maxObjects_) {
                return node; // The stack has reached the maximum number of objects.
            }

            // Set the new head of the stack and update the oldest location.
            HeadType newHead = HeadType(oldHead.GetCount() + 1, node);

            // Is 'head' still the same?
            if(oldHead == Memory::ReadValue(&head_)) {
                // Link the node to the current head of the stack.
                node->Next = oldHead.GetFirst();

                if(CompareExchange(oldHead, newHead)) {
                    T* temp = newHead.GetFirst();
                    temp->Next = temp->Next;
                    return nullptr; // The head was successfully updated.
                }
            }

            if((++waitCount % 50) == 0) {
                // Give threads with a lower priority a chance to run.
                ThreadUtils::SwitchToThread();
            }
            else {
                // Back off.
                for(int i = 0; i < waitCount; i++) {
                    ThreadUtils::Wait();
                }
            }
        }
    }