blob: 2f015a4d2261d039d14c65bae7ada07d36c63d6e [file] [log] [blame]
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001#ifndef NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
2#define NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
Jeff Thompsonf7d49942013-08-01 16:47:40 -07003
4//
5// Copyright (c) 2008, 2011 Peter Dimov
6//
7// Distributed under the Boost Software License, Version 1.0.
8// See accompanying file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11
Jeff Thompson2277ce52013-08-01 17:34:11 -070012#include <ndnboost/smart_ptr/detail/yield_k.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070013
14#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
15
Jeff Thompson3d613fd2013-10-15 15:39:04 -070016# define NDNBOOST_SP_ARM_BARRIER "dmb"
17# define NDNBOOST_SP_ARM_HAS_LDREX
Jeff Thompsonf7d49942013-08-01 16:47:40 -070018
19#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
20
Jeff Thompson3d613fd2013-10-15 15:39:04 -070021# define NDNBOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
22# define NDNBOOST_SP_ARM_HAS_LDREX
Jeff Thompsonf7d49942013-08-01 16:47:40 -070023
24#else
25
Jeff Thompson3d613fd2013-10-15 15:39:04 -070026# define NDNBOOST_SP_ARM_BARRIER ""
Jeff Thompsonf7d49942013-08-01 16:47:40 -070027
28#endif
29
30namespace ndnboost
31{
32
33namespace detail
34{
35
36class spinlock
37{
38public:
39
40 int v_;
41
42public:
43
44 bool try_lock()
45 {
46 int r;
47
Jeff Thompson3d613fd2013-10-15 15:39:04 -070048#ifdef NDNBOOST_SP_ARM_HAS_LDREX
Jeff Thompsonf7d49942013-08-01 16:47:40 -070049
50 __asm__ __volatile__(
51 "ldrex %0, [%2]; \n"
52 "cmp %0, %1; \n"
53 "strexne %0, %1, [%2]; \n"
Jeff Thompson3d613fd2013-10-15 15:39:04 -070054 NDNBOOST_SP_ARM_BARRIER :
Jeff Thompsonf7d49942013-08-01 16:47:40 -070055 "=&r"( r ): // outputs
56 "r"( 1 ), "r"( &v_ ): // inputs
57 "memory", "cc" );
58
59#else
60
61 __asm__ __volatile__(
62 "swp %0, %1, [%2];\n"
Jeff Thompson3d613fd2013-10-15 15:39:04 -070063 NDNBOOST_SP_ARM_BARRIER :
Jeff Thompsonf7d49942013-08-01 16:47:40 -070064 "=&r"( r ): // outputs
65 "r"( 1 ), "r"( &v_ ): // inputs
66 "memory", "cc" );
67
68#endif
69
70 return r == 0;
71 }
72
73 void lock()
74 {
75 for( unsigned k = 0; !try_lock(); ++k )
76 {
77 ndnboost::detail::yield( k );
78 }
79 }
80
81 void unlock()
82 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070083 __asm__ __volatile__( NDNBOOST_SP_ARM_BARRIER ::: "memory" );
Jeff Thompsonf7d49942013-08-01 16:47:40 -070084 *const_cast< int volatile* >( &v_ ) = 0;
85 }
86
87public:
88
89 class scoped_lock
90 {
91 private:
92
93 spinlock & sp_;
94
95 scoped_lock( scoped_lock const & );
96 scoped_lock & operator=( scoped_lock const & );
97
98 public:
99
100 explicit scoped_lock( spinlock & sp ): sp_( sp )
101 {
102 sp.lock();
103 }
104
105 ~scoped_lock()
106 {
107 sp_.unlock();
108 }
109 };
110};
111
112} // namespace detail
113} // namespace ndnboost
114
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700115#define NDNBOOST_DETAIL_SPINLOCK_INIT {0}
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700116
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700117#undef NDNBOOST_SP_ARM_BARRIER
118#undef NDNBOOST_SP_ARM_HAS_LDREX
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700119
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700120#endif // #ifndef NDNBOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED