forked from boostorg/smart_ptr
Split winapi.hpp across win32-specific headers, added BOOST_USE_WINDOWS_H option.
[SVN r17277]
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
// boost/detail/atomic_count_win32.hpp
|
// boost/detail/atomic_count_win32.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
@ -16,7 +16,9 @@
|
|||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/winapi.hpp>
|
#ifdef BOOST_USE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -24,6 +26,37 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||||
|
|
||||||
|
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
|
||||||
|
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
|
||||||
|
|
||||||
|
#pragma intrinsic(_InterlockedIncrement)
|
||||||
|
#pragma intrinsic(_InterlockedDecrement)
|
||||||
|
|
||||||
|
inline long InterlockedIncrement(long volatile * lp)
|
||||||
|
{
|
||||||
|
return _InterlockedIncrement(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long InterlockedDecrement(long volatile* lp)
|
||||||
|
{
|
||||||
|
return _InterlockedDecrement(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // _WIN64
|
||||||
|
|
||||||
|
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
|
||||||
|
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
|
||||||
|
|
||||||
|
#endif // _WIN64
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
class atomic_count
|
class atomic_count
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -34,12 +67,13 @@ public:
|
|||||||
|
|
||||||
long operator++()
|
long operator++()
|
||||||
{
|
{
|
||||||
return winapi::InterlockedIncrement(&value_);
|
// Some older <windows.h> versions do not accept volatile
|
||||||
|
return InterlockedIncrement(const_cast<long*>(&value_));
|
||||||
}
|
}
|
||||||
|
|
||||||
long operator--()
|
long operator--()
|
||||||
{
|
{
|
||||||
return winapi::InterlockedDecrement(&value_);
|
return InterlockedDecrement(const_cast<long*>(&value_));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator long() const
|
operator long() const
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
// boost/detail/lwm_win32.hpp
|
// boost/detail/lwm_win32.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2002, 2003 Peter Dimov
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
@ -16,7 +16,9 @@
|
|||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/winapi.hpp>
|
#ifdef BOOST_USE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
# pragma warn -8027 // Functions containing while are not expanded inline
|
# pragma warn -8027 // Functions containing while are not expanded inline
|
||||||
@ -28,6 +30,31 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||||
|
|
||||||
|
extern "C" long_type __cdecl _InterlockedExchange(long volatile *, long);
|
||||||
|
|
||||||
|
#pragma intrinsic(_InterlockedExchange)
|
||||||
|
|
||||||
|
inline long InterlockedExchange(long volatile* lp, long l)
|
||||||
|
{
|
||||||
|
return _InterlockedExchange(lp, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // _WIN64
|
||||||
|
|
||||||
|
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
|
||||||
|
|
||||||
|
#endif // _WIN64
|
||||||
|
|
||||||
|
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
class lightweight_mutex
|
class lightweight_mutex
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -59,20 +86,20 @@ public:
|
|||||||
|
|
||||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||||
{
|
{
|
||||||
while( winapi::InterlockedExchange(&m_.l_, 1) )
|
while( InterlockedExchange(&m_.l_, 1) )
|
||||||
{
|
{
|
||||||
// Note: changed to Sleep(1) from Sleep(0).
|
// Note: changed to Sleep(1) from Sleep(0).
|
||||||
// According to MSDN, Sleep(0) will never yield
|
// According to MSDN, Sleep(0) will never yield
|
||||||
// to a lower-priority thread, whereas Sleep(1)
|
// to a lower-priority thread, whereas Sleep(1)
|
||||||
// will. Performance seems not to be affected.
|
// will. Performance seems not to be affected.
|
||||||
|
|
||||||
winapi::Sleep(1);
|
Sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~scoped_lock()
|
~scoped_lock()
|
||||||
{
|
{
|
||||||
winapi::InterlockedExchange(&m_.l_, 0);
|
InterlockedExchange(&m_.l_, 0);
|
||||||
|
|
||||||
// Note: adding a yield here will make
|
// Note: adding a yield here will make
|
||||||
// the spinlock more fair and will increase the overall
|
// the spinlock more fair and will increase the overall
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
// boost/detail/lwm_win32_cs.hpp
|
// boost/detail/lwm_win32_cs.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2002, 2003 Peter Dimov
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
@ -16,7 +16,9 @@
|
|||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/winapi.hpp>
|
#ifdef BOOST_USE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -24,11 +26,34 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
|
struct CRITICAL_SECTION
|
||||||
|
{
|
||||||
|
struct critical_section_debug * DebugInfo;
|
||||||
|
long LockCount;
|
||||||
|
long RecursionCount;
|
||||||
|
void * OwningThread;
|
||||||
|
void * LockSemaphore;
|
||||||
|
#if defined(_WIN64)
|
||||||
|
unsigned __int64 SpinCount;
|
||||||
|
#else
|
||||||
|
unsigned long SpinCount;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
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 *);
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||||
|
|
||||||
class lightweight_mutex
|
class lightweight_mutex
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
winapi::critical_section cs_;
|
CRITICAL_SECTION cs_;
|
||||||
|
|
||||||
lightweight_mutex(lightweight_mutex const &);
|
lightweight_mutex(lightweight_mutex const &);
|
||||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||||
@ -37,12 +62,12 @@ public:
|
|||||||
|
|
||||||
lightweight_mutex()
|
lightweight_mutex()
|
||||||
{
|
{
|
||||||
winapi::InitializeCriticalSection(&cs_);
|
InitializeCriticalSection(&cs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~lightweight_mutex()
|
~lightweight_mutex()
|
||||||
{
|
{
|
||||||
winapi::DeleteCriticalSection(&cs_);
|
DeleteCriticalSection(&cs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
class scoped_lock;
|
class scoped_lock;
|
||||||
@ -61,12 +86,12 @@ public:
|
|||||||
|
|
||||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||||
{
|
{
|
||||||
winapi::EnterCriticalSection(&m_.cs_);
|
EnterCriticalSection(&m_.cs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~scoped_lock()
|
~scoped_lock()
|
||||||
{
|
{
|
||||||
winapi::LeaveCriticalSection(&m_.cs_);
|
LeaveCriticalSection(&m_.cs_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
#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;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
|
|
||||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
|
||||||
|
|
||||||
extern "C" long_type __cdecl _InterlockedIncrement(long_type volatile *);
|
|
||||||
extern "C" long_type __cdecl _InterlockedDecrement(long_type volatile *);
|
|
||||||
extern "C" long_type __cdecl _InterlockedExchange(long_type volatile *, long_type);
|
|
||||||
|
|
||||||
#pragma intrinsic(_InterlockedIncrement)
|
|
||||||
#pragma intrinsic(_InterlockedDecrement)
|
|
||||||
#pragma intrinsic(_InterlockedExchange)
|
|
||||||
|
|
||||||
inline long_type InterlockedIncrement(long_type volatile * lp)
|
|
||||||
{
|
|
||||||
return _InterlockedIncrement(lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline long_type InterlockedDecrement(long_type volatile* lp)
|
|
||||||
{
|
|
||||||
return _InterlockedDecrement(lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline long_type InterlockedExchange(long_type volatile* lp, long_type l)
|
|
||||||
{
|
|
||||||
return _InterlockedExchange(lp, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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
|
|
@ -152,11 +152,13 @@ int const m = 16; // threads
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::printf("%s: %s, %d threads, %d iterations: ", title, implementation, m, n);
|
using namespace std; // printf, clock_t, clock
|
||||||
|
|
||||||
|
printf("%s: %s, %d threads, %d iterations: ", title, implementation, m, n);
|
||||||
|
|
||||||
boost::shared_ptr<int> pi(new int(42));
|
boost::shared_ptr<int> pi(new int(42));
|
||||||
|
|
||||||
std::clock_t t = std::clock();
|
clock_t t = clock();
|
||||||
|
|
||||||
pthread_t a[m];
|
pthread_t a[m];
|
||||||
|
|
||||||
@ -165,14 +167,14 @@ int main()
|
|||||||
a[i] = createThread( boost::bind(test, pi) );
|
a[i] = createThread( boost::bind(test, pi) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < m; ++i)
|
for(int j = 0; j < m; ++j)
|
||||||
{
|
{
|
||||||
pthread_join(a[i], 0);
|
pthread_join(a[j], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = std::clock() - t;
|
t = clock() - t;
|
||||||
|
|
||||||
std::printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
|
printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -25,17 +25,21 @@ int const n = 8 * 1024 * 1024;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
std::vector< boost::shared_ptr<int> > v;
|
std::vector< boost::shared_ptr<int> > v;
|
||||||
boost::shared_ptr<int> pi(new int);
|
boost::shared_ptr<int> pi(new int);
|
||||||
|
|
||||||
std::clock_t t = std::clock();
|
clock_t t = clock();
|
||||||
|
|
||||||
for(int i = 0; i < n; ++i)
|
for(int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
v.push_back(pi);
|
v.push_back(pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = std::clock() - t;
|
t = clock() - t;
|
||||||
|
|
||||||
std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
|
std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user