Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ready] William's queue - SPSC and MPMC #103

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dudovlad
Copy link

No description provided.

@dudovlad dudovlad changed the title Add william's container without working stress tests [Ready] William's queue - SPSC and MPMC Mar 1, 2018
@dudovlad
Copy link
Author

dudovlad commented Mar 1, 2018

Добавлена очередь SPSC, вместе с unit и stress тестами.
Исправлена ошибка сборки stress тестов очереди MPMC. Однако некоторый stress тесты не проходят, по причине SegFault.

SegFault появляется в строке 426 в классе WilliamsQueue. Это происходит, потому что переменная old_head равна nullptr.

@khizmax
Copy link
Owner

khizmax commented Mar 3, 2018

Переменная old_head не может быть равной nullptr, так как она - не указатель.

@dudovlad
Copy link
Author

dudovlad commented Mar 3, 2018

Ошибка не в 425, а в 426 строке.

counted_node_ptr next = p->m_next.load();

Там p = nullptr. Соответственно old_head = nullptr.

@khizmax
Copy link
Owner

khizmax commented Mar 3, 2018

Если я нигде не наврал, то вот usecase:

bool dequeue_with(Func f)
{
    // Предположим,  очередь пуста.
    counted_node_ptr old_head = m_Head.load(atomics::memory_order_relaxed);
    // Раз очередь пуста, то m_Head.ptr ==  m_Tail.ptr
    // и old_head.ptr->m_next == nullptr
     while (true) {
	increase_external_count(m_Head, old_head);
	node_type * const p = old_head.ptr;
       // Thread preempted. Другой поток вставляет элемент в очередь
       // Раз вставляет - m_Tail изменился
       // Тогда сравнение с m_Tail не пройдет
	if (p == m_Tail.load().ptr) 	{
		release_ref(p);
		return false;
	}
       // а здесь у нас p->m_next == nullptr !!!
	counted_node_ptr next = p->m_next.load();
	if (m_Head.compare_exchange_strong(old_head, next))
	{
		scoped_value_ptr res(p->m_value.load());
		free_external_counter(old_head); 
		--m_ItemCounter;
		f(*res.get());
		return true;
	}
	release_ref(p);
   }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants