- 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
|
// The code of the hash() function in the critical section table
// came from the MSDN article written by Ian Emmons,
// "Multiprocessor Optimizations: Fine-Tuning Concurrent Access to Large Data Collections",
// http://msdn.microsoft.com/en-ca/magazine/cc301503.aspx
#pragma once
#include "stdafx.h"
#include "rwlocks_helpers.h"
template <typename Lock_type>
struct CritSecTable_locker_t
{
typedef ref_exclusive_lock_t<Lock_type> Exclusive_lock;
typedef ref_shared_lock_t<Lock_type> Shared_lock;
unsigned char hash(void* p)
{
unsigned char result;
if (sizeof(void*) == 8)
{
assert(sizeof(unsigned long) == 4);
assert(sizeof(unsigned short) == 2);
unsigned long temp1 = ((unsigned long*) (&p))[0]
^ ((unsigned long*) (&p))[1];
unsigned short temp2 = ((unsigned short*) (&temp1))[0]
^ ((unsigned short*) (&temp1))[1];
result = ((unsigned char*) (&temp2))[0]
^ ((unsigned char*) (&temp2))[1];
}
else if (sizeof(void*) == 4)
{
assert(sizeof(unsigned short) == 2);
unsigned short temp = ((unsigned short*) (&p))[0]
^ ((unsigned short*) (&p))[1];
result = ((unsigned char*) (&temp))[0]
^ ((unsigned char*) (&temp))[1];
}
else
{
result = ((unsigned char*) (&p))[0];
for (unsigned i = 1; i < sizeof(void*); i++)
{
result ^= ((unsigned char*) (&p))[i];
}
}
return result;
}
Lock_type& get_element_lock(void* p)
{
return m_element_locks[hash(p)];
}
enum {CSTABLE_SIZE = 256};
Lock_type m_element_locks[CSTABLE_SIZE];
CACHE_PADDING1
Lock_type m_global_scope_lock;
CritSecTable_locker_t& operator=(const CritSecTable_locker_t&); //C4512 warning
};
template <typename key_type, typename value_type, typename lock_type>
class CST_map_t
{
public:
bool insert( const std::pair<key_type, value_type>& pair)
{
Container_locker::Exclusive_lock lock(m_map_lock.m_global_scope_lock);
return m_map.insert(pair).second;
}
bool erase(const key_type& _key)
{
Container_locker::Exclusive_lock lock(m_map_lock.m_global_scope_lock);
return (m_map.erase(_key) != 0);
}
bool update(const key_type& _key, const value_type& _val)
{
Container_locker::Shared_lock lock(m_map_lock.m_global_scope_lock);
map_iterator iterator = m_map.find(_key);
if (iterator != m_map.end())
{
Container_locker::Exclusive_lock lock(m_map_lock.get_element_lock(&iterator->second));
iterator->second = _val;
return true;
}
else
{
return false;
}
}
bool find(const key_type& _key, value_type& _val)
{
Container_locker::Shared_lock lock(m_map_lock.m_global_scope_lock);
map_iterator iterator = m_map.find(_key);
if (iterator != m_map.end())
{
Container_locker::Shared_lock lock(m_map_lock.get_element_lock(&iterator->second));
_val = iterator->second;
return true;
}
else
{
return false;
}
}
private:
typedef CritSecTable_locker_t<lock_type> Container_locker;
#ifdef HAS_HASH_MAP
typedef typename stdext::hash_map<key_type, value_type>::iterator map_iterator;
stdext::hash_map<key_type, value_type> m_map;
#elif defined HAS_MAP
typedef typename std::map<key_type, value_type>::iterator map_iterator;
std::map<key_type, value_type> m_map;
#endif
CACHE_PADDING1
Container_locker m_map_lock;
};
|
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.