Split winapi.hpp across win32-specific headers, added BOOST_USE_WINDOWS_H option.

[SVN r17277]
This commit is contained in:
Peter Dimov
2003-02-08 16:05:46 +00:00
parent 4b502993b5
commit 4244992d4d
6 changed files with 116 additions and 130 deletions

View File

@ -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

View File

@ -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

View File

@ -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_);
}
};
};

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}