- container_locks.zip
- Container_locks
- src
- Testing_simple_concurrent_containers.pdf
- VC9
- container_locks.sln
- container_locks.vcproj
- container_locks.vcproj.val-PC.val.user
- Debug
- Debug64
- Release
- Release64
|
/*
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.