comparison DEPENDENCIES/generic/include/boost/interprocess/sync/spin/mutex.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_INTERPROCESS_DETAIL_SPIN_MUTEX_HPP
12 #define BOOST_INTERPROCESS_DETAIL_SPIN_MUTEX_HPP
13
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif
17
18 #include <boost/interprocess/detail/config_begin.hpp>
19 #include <boost/interprocess/detail/workaround.hpp>
20 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
21 #include <boost/assert.hpp>
22 #include <boost/interprocess/detail/atomic.hpp>
23 #include <boost/cstdint.hpp>
24 #include <boost/interprocess/detail/os_thread_functions.hpp>
25 #include <boost/interprocess/sync/spin/wait.hpp>
26
27 namespace boost {
28 namespace interprocess {
29 namespace ipcdetail {
30
31 class spin_mutex
32 {
33 spin_mutex(const spin_mutex &);
34 spin_mutex &operator=(const spin_mutex &);
35 public:
36
37 spin_mutex();
38 ~spin_mutex();
39
40 void lock();
41 bool try_lock();
42 bool timed_lock(const boost::posix_time::ptime &abs_time);
43 void unlock();
44 void take_ownership(){};
45 private:
46 volatile boost::uint32_t m_s;
47 };
48
49 inline spin_mutex::spin_mutex()
50 : m_s(0)
51 {
52 //Note that this class is initialized to zero.
53 //So zeroed memory can be interpreted as an
54 //initialized mutex
55 }
56
57 inline spin_mutex::~spin_mutex()
58 {
59 //Trivial destructor
60 }
61
62 inline void spin_mutex::lock(void)
63 {
64 spin_wait swait;
65 do{
66 boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
67
68 if (m_s == 1 && prev_s == 0){
69 break;
70 }
71 // relinquish current timeslice
72 swait.yield();
73 }while (true);
74 }
75
76 inline bool spin_mutex::try_lock(void)
77 {
78 boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
79 return m_s == 1 && prev_s == 0;
80 }
81
82 inline bool spin_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
83 {
84 if(abs_time == boost::posix_time::pos_infin){
85 this->lock();
86 return true;
87 }
88 //Obtain current count and target time
89 boost::posix_time::ptime now = microsec_clock::universal_time();
90
91 spin_wait swait;
92 do{
93 if(this->try_lock()){
94 break;
95 }
96 now = microsec_clock::universal_time();
97
98 if(now >= abs_time){
99 return false;
100 }
101 // relinquish current time slice
102 swait.yield();
103 }while (true);
104
105 return true;
106 }
107
108 inline void spin_mutex::unlock(void)
109 { ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 0, 1); }
110
111 } //namespace ipcdetail {
112 } //namespace interprocess {
113 } //namespace boost {
114
115 #include <boost/interprocess/detail/config_end.hpp>
116
117 #endif //BOOST_INTERPROCESS_DETAIL_SPIN_MUTEX_HPP