Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Testing simple concurrent containers

, 25 Oct 2009
This article illustrates simple approaches and test results when creating containers with concurrent flavor and running on a multi-core PC.
container_locks.zip
Container_locks
src
Testing_simple_concurrent_containers.pdf
VC9
container_locks.vcproj.val-PC.val.user
Debug
tbb_debug.dll
Debug64
tbb_debug.dll
Release
tbb.dll
Release64
tbb.dll
/*
This is the code of the Pool_of_shared_elements crash test. The purpose of this code is to show
that the minimum size of the pool Pool_of_shared_elements is (2*number_of_threads-1).
If the size of the pool is smaller, the pool may crash. The probability of such failure is low
for large containers - and it might be difficult to spot it out when debugging the application.
This code simulates holding of two pool elements by one thread, when a shared pool element is
already popped by another thread.
*/

#pragma once
#include "pool_t.h"
#include <map>

template <typename Entry_t, WORD number_of_threads,
const size_t pool_size = (2*number_of_threads-1)/* this is the minimum size of the pool*/> 

class CACHE_ALIGN Pool_of_shared_elements_crash_test: 
private Pool_t<Entry_t, pool_size - 1 /*set the pool_size smaller than (2*number_of_threads-1) to crash it*/>
{
public:
	WORD pop(volatile LONG& reference_counter)
	{
		LONG i;
		LONG j;
		LONG exch_counter;

		WORD new_index = static_cast<WORD>(__super::pop());

		if (new_index == 0)
		{
			::MessageBox(0, _T("There are no free elements in the pool."), 
				_T("Pool_of_shared_elements_crash_test application."), 0);
			return 0; /* error */ 
		}
		else
		{
		}

		j = acquire_read(reference_counter);
		do
		{
			exch_counter = (HIWORD(j) == 0)? ((LONG)new_index << 16) | (LOWORD(j) + 1) : j + 1;
			i = j;
			j = acquire_interlocked_compare_exchange(&reference_counter,
							exch_counter,
							i);
			PAUSE

		} while(i != j);

		WORD index = HIWORD(exch_counter); 

		if ( index != new_index)
		{
			////////////////////////////
			// crash code
			Pool_element_pair pool_pair;
			//keep indexes for debug purposes, to see the pool elements which are already popped from the pool
			pool_pair.m_index1 = index;
			pool_pair.m_index2 = new_index;
			::EnterCriticalSection(&m_cs);
			bool rc = m_pool_pairs.insert(std::map<int, Pool_element_pair>::value_type(index, pool_pair)).second;
			::LeaveCriticalSection(&m_cs);
			if (true == rc)
			{
				//now, one thread holds two pool elements
				::Sleep(INFINITE);
			}
			// end crash code
			////////////////////////////

			__super::push( new_index );
		}
		else
		{
		}

		return index;
	}

	void push(WORD index, volatile LONG& reference_counter)
	{
		LONG counter = interlocked_decrement_release(&reference_counter);
		if (LOWORD(counter) == 0)
		{
			if ( counter == acquire_interlocked_compare_exchange(&reference_counter, 0x0, counter))
			{
				__super::push( index );
			}
			else
			{
			}
		}
		else
		{
		}
	}

	inline Entry_t* get(WORD index)
	{
		return __super::get(index);
	}

	////////////////////////////
	// crash code
	struct Pool_element_pair {
		int m_index1;
		int m_index2;
	};
	std::map<int, Pool_element_pair> m_pool_pairs;
	CRITICAL_SECTION m_cs;
	Pool_of_shared_elements_crash_test() {	::InitializeCriticalSection(&m_cs); }
	~Pool_of_shared_elements_crash_test() {	::DeleteCriticalSection(&m_cs); }
	// end crash code
	////////////////////////////

};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Valery Grebnev
Software Developer
Canada Canada
No Biography provided

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 25 Oct 2009
Article Copyright 2009 by Valery Grebnev
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid