blob: 021e3b0e6f2a0ae054153a71f034d4db4537702c [file] [log] [blame]
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001#ifndef NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
2#define NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
Jeff Thompsonf7d49942013-08-01 16:47:40 -07003
4// MS compatible compilers support #pragma once
5
6#if defined(_MSC_VER) && (_MSC_VER >= 1020)
7# pragma once
8#endif
9
10//
11// Copyright (c) 2008 Peter Dimov
12//
13// Distributed under the Boost Software License, Version 1.0.
14// See accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16//
17
Jeff Thompson2277ce52013-08-01 17:34:11 -070018#include <ndnboost/detail/interlocked.hpp>
19#include <ndnboost/smart_ptr/detail/yield_k.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070020
Jeff Thompson3d613fd2013-10-15 15:39:04 -070021// NDNBOOST_COMPILER_FENCE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070022
23#if defined(__INTEL_COMPILER)
24
Jeff Thompson3d613fd2013-10-15 15:39:04 -070025#define NDNBOOST_COMPILER_FENCE __memory_barrier();
Jeff Thompsonf7d49942013-08-01 16:47:40 -070026
27#elif defined( _MSC_VER ) && _MSC_VER >= 1310
28
29extern "C" void _ReadWriteBarrier();
30#pragma intrinsic( _ReadWriteBarrier )
31
Jeff Thompson3d613fd2013-10-15 15:39:04 -070032#define NDNBOOST_COMPILER_FENCE _ReadWriteBarrier();
Jeff Thompsonf7d49942013-08-01 16:47:40 -070033
34#elif defined(__GNUC__)
35
Jeff Thompson3d613fd2013-10-15 15:39:04 -070036#define NDNBOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
Jeff Thompsonf7d49942013-08-01 16:47:40 -070037
38#else
39
Jeff Thompson3d613fd2013-10-15 15:39:04 -070040#define NDNBOOST_COMPILER_FENCE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070041
42#endif
43
44//
45
46namespace ndnboost
47{
48
49namespace detail
50{
51
52class spinlock
53{
54public:
55
56 long v_;
57
58public:
59
60 bool try_lock()
61 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070062 long r = NDNBOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
Jeff Thompsonf7d49942013-08-01 16:47:40 -070063
Jeff Thompson3d613fd2013-10-15 15:39:04 -070064 NDNBOOST_COMPILER_FENCE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070065
66 return r == 0;
67 }
68
69 void lock()
70 {
71 for( unsigned k = 0; !try_lock(); ++k )
72 {
73 ndnboost::detail::yield( k );
74 }
75 }
76
77 void unlock()
78 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070079 NDNBOOST_COMPILER_FENCE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070080 *const_cast< long volatile* >( &v_ ) = 0;
81 }
82
83public:
84
85 class scoped_lock
86 {
87 private:
88
89 spinlock & sp_;
90
91 scoped_lock( scoped_lock const & );
92 scoped_lock & operator=( scoped_lock const & );
93
94 public:
95
96 explicit scoped_lock( spinlock & sp ): sp_( sp )
97 {
98 sp.lock();
99 }
100
101 ~scoped_lock()
102 {
103 sp_.unlock();
104 }
105 };
106};
107
108} // namespace detail
109} // namespace ndnboost
110
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700111#define NDNBOOST_DETAIL_SPINLOCK_INIT {0}
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700112
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700113#endif // #ifndef NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED