Added winapi.hpp and a CRITICAL_SECTION lightweight_mutex variant.

[SVN r13211]
This commit is contained in:
Peter Dimov
2002-03-15 22:00:10 +00:00
parent 220f35a0f1
commit b89945d36a
7 changed files with 185 additions and 26 deletions

View File

@ -91,12 +91,14 @@ typedef long atomic_count;
}
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/atomic_count_win32.hpp>
//#elif defined(linux) || defined(__linux) || defined(__linux__)
#elif defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/atomic_count_linux.hpp>
#elif defined(BOOST_AC_USE_PTHREADS)
# include <boost/detail/atomic_count_pthreads.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/atomic_count_win32.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS
# include <boost/detail/atomic_count_pthreads.hpp>
#else

View File

@ -19,11 +19,9 @@
// inefficiencies. Example: a class with two atomic_count members
// can get away with a single mutex.
//
// Define a macro so that users can detect the situation and optimize.
// Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
//
#define BOOST_ATOMIC_COUNT_USES_PTHREADS
namespace boost
{

View File

@ -16,20 +16,14 @@
// warranty, and with no claim as to its suitability for any purpose.
//
#include <boost/detail/winapi.hpp>
namespace boost
{
namespace detail
{
// Avoid #including <windows.h>
namespace win32
{
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
}
class atomic_count
{
public:
@ -40,12 +34,12 @@ public:
long operator++()
{
return win32::InterlockedIncrement(&value_);
return winapi::InterlockedIncrement(&value_);
}
long operator--()
{
return win32::InterlockedDecrement(&value_);
return winapi::InterlockedDecrement(&value_);
}
operator long() const

View File

@ -37,16 +37,28 @@
#include <boost/config.hpp>
//
// Note to implementors: if you write a platform-specific lightweight_mutex
// for a platform that supports pthreads, be sure to test its performance
// against the pthreads-based version using smart_ptr_timing_test.cpp and
// smart_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
// _unless_ the performance gains are substantial.
//
#ifndef BOOST_HAS_THREADS
# include <boost/detail/lwm_nop.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/lwm_win32.hpp>
//#elif defined(linux) || defined(__linux) || defined(__linux__)
#elif defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/lwm_linux.hpp>
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
# include <boost/detail/lwm_win32_cs.hpp>
#elif defined(BOOST_LWM_USE_PTHREADS)
# include <boost/detail/lwm_pthreads.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/lwm_win32.hpp>
#elif defined(__sgi)
# include <boost/detail/lwm_irix.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_LWM_USE_PTHREADS
# include <boost/detail/lwm_pthreads.hpp>
#else
# include <boost/detail/lwm_nop.hpp>

View File

@ -16,17 +16,14 @@
// warranty, and with no claim as to its suitability for any purpose.
//
#include <boost/detail/winapi.hpp>
namespace boost
{
namespace detail
{
// avoid including <windows.h>
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
class lightweight_mutex
{
private:
@ -58,12 +55,15 @@ public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
while( InterlockedExchange(&m_.l_, 1) ) Sleep(0);
while( winapi::InterlockedExchange(&m_.l_, 1) )
{
winapi::Sleep(0);
}
}
~scoped_lock()
{
InterlockedExchange(&m_.l_, 0);
winapi::InterlockedExchange(&m_.l_, 0);
// Note: adding a Sleep(0) here will make
// the mutex more fair and will increase the overall

View File

@ -0,0 +1,78 @@
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/detail/lwm_win32_cs.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
#include <boost/detail/winapi.hpp>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
winapi::critical_section cs_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex()
{
winapi::InitializeCriticalSection(&cs_);
}
~lightweight_mutex()
{
winapi::DeleteCriticalSection(&cs_);
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
winapi::EnterCriticalSection(&m_.cs_);
}
~scoped_lock()
{
winapi::LeaveCriticalSection(&m_.cs_);
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED

View File

@ -0,0 +1,75 @@
#ifndef BOOST_DETAIL_WINAPI_HPP_INCLUDED
#define BOOST_DETAIL_WINAPI_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/detail/winapi.hpp - a lightweight version of <windows.h>
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
namespace boost
{
namespace detail
{
namespace winapi
{
typedef long long_type;
typedef unsigned long dword_type;
typedef void * handle_type;
#if defined(_WIN64)
typedef __int64 int_ptr_type;
typedef unsigned __int64 uint_ptr_type;
typedef __int64 long_ptr_type;
typedef unsigned __int64 ulong_ptr_type;
#else
typedef int int_ptr_type;
typedef unsigned int uint_ptr_type;
typedef long long_ptr_type;
typedef unsigned long ulong_ptr_type;
#endif
struct critical_section
{
struct critical_section_debug * DebugInfo;
long_type LockCount;
long_type RecursionCount;
handle_type OwningThread;
handle_type LockSemaphore;
ulong_ptr_type SpinCount;
};
extern "C" __declspec(dllimport) long_type __stdcall InterlockedIncrement(long_type volatile *);
extern "C" __declspec(dllimport) long_type __stdcall InterlockedDecrement(long_type volatile *);
extern "C" __declspec(dllimport) long_type __stdcall InterlockedExchange(long_type volatile *, long_type);
extern "C" __declspec(dllimport) void __stdcall Sleep(dword_type);
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
} // namespace winapi
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_WINAPI_HPP_INCLUDED