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
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <boost/detail/winapi.hpp>
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -24,6 +26,37 @@ namespace boost
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -34,12 +67,13 @@ public:
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return winapi::InterlockedIncrement(&value_);
|
||||
// Some older <windows.h> versions do not accept volatile
|
||||
return InterlockedIncrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return winapi::InterlockedDecrement(&value_);
|
||||
return InterlockedDecrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
operator long() const
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <boost/detail/winapi.hpp>
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8027 // Functions containing while are not expanded inline
|
||||
@ -28,6 +30,31 @@ namespace boost
|
||||
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
|
||||
{
|
||||
private:
|
||||
@ -59,20 +86,20 @@ public:
|
||||
|
||||
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).
|
||||
// According to MSDN, Sleep(0) will never yield
|
||||
// to a lower-priority thread, whereas Sleep(1)
|
||||
// will. Performance seems not to be affected.
|
||||
|
||||
winapi::Sleep(1);
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
winapi::InterlockedExchange(&m_.l_, 0);
|
||||
InterlockedExchange(&m_.l_, 0);
|
||||
|
||||
// Note: adding a yield here will make
|
||||
// the spinlock more fair and will increase the overall
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <boost/detail/winapi.hpp>
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -24,11 +26,34 @@ namespace boost
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
||||
winapi::critical_section cs_;
|
||||
CRITICAL_SECTION cs_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
@ -37,12 +62,12 @@ public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
winapi::InitializeCriticalSection(&cs_);
|
||||
InitializeCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
winapi::DeleteCriticalSection(&cs_);
|
||||
DeleteCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
@ -61,12 +86,12 @@ public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
winapi::EnterCriticalSection(&m_.cs_);
|
||||
EnterCriticalSection(&m_.cs_);
|
||||
}
|
||||
|
||||
~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()
|
||||
{
|
||||
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));
|
||||
|
||||
std::clock_t t = std::clock();
|
||||
clock_t t = clock();
|
||||
|
||||
pthread_t a[m];
|
||||
|
||||
@ -165,14 +167,14 @@ int main()
|
||||
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;
|
||||
}
|
||||
|
@ -25,17 +25,21 @@ int const n = 8 * 1024 * 1024;
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
std::vector< boost::shared_ptr<int> > v;
|
||||
boost::shared_ptr<int> pi(new int);
|
||||
|
||||
std::clock_t t = std::clock();
|
||||
clock_t t = clock();
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
v.push_back(pi);
|
||||
}
|
||||
|
||||
t = std::clock() - t;
|
||||
t = clock() - t;
|
||||
|
||||
std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user