xref: /freebsd-12.1/contrib/libc++/src/memory.cpp (revision b1d04644)
1 //===------------------------ memory.cpp ----------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "memory"
11 
12 _LIBCPP_BEGIN_NAMESPACE_STD
13 
14 namespace
15 {
16 
17 template <class T>
18 inline T
19 increment(T& t) _NOEXCEPT
20 {
21     return __sync_add_and_fetch(&t, 1);
22 }
23 
24 template <class T>
25 inline T
26 decrement(T& t) _NOEXCEPT
27 {
28     return __sync_add_and_fetch(&t, -1);
29 }
30 
31 }  // namespace
32 
33 const allocator_arg_t allocator_arg = allocator_arg_t();
34 
35 bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
36 
37 const char*
38 bad_weak_ptr::what() const _NOEXCEPT
39 {
40     return "bad_weak_ptr";
41 }
42 
43 __shared_count::~__shared_count()
44 {
45 }
46 
47 void
48 __shared_count::__add_shared() _NOEXCEPT
49 {
50     increment(__shared_owners_);
51 }
52 
53 bool
54 __shared_count::__release_shared() _NOEXCEPT
55 {
56     if (decrement(__shared_owners_) == -1)
57     {
58         __on_zero_shared();
59         return true;
60     }
61     return false;
62 }
63 
64 __shared_weak_count::~__shared_weak_count()
65 {
66 }
67 
68 void
69 __shared_weak_count::__add_shared() _NOEXCEPT
70 {
71     __shared_count::__add_shared();
72 }
73 
74 void
75 __shared_weak_count::__add_weak() _NOEXCEPT
76 {
77     increment(__shared_weak_owners_);
78 }
79 
80 void
81 __shared_weak_count::__release_shared() _NOEXCEPT
82 {
83     if (__shared_count::__release_shared())
84         __release_weak();
85 }
86 
87 void
88 __shared_weak_count::__release_weak() _NOEXCEPT
89 {
90     if (decrement(__shared_weak_owners_) == -1)
91         __on_zero_shared_weak();
92 }
93 
94 __shared_weak_count*
95 __shared_weak_count::lock() _NOEXCEPT
96 {
97     long object_owners = __shared_owners_;
98     while (object_owners != -1)
99     {
100         if (__sync_bool_compare_and_swap(&__shared_owners_,
101                                          object_owners,
102                                          object_owners+1))
103         {
104             __add_weak();
105             return this;
106         }
107         object_owners = __shared_owners_;
108     }
109     return 0;
110 }
111 
112 #ifndef _LIBCPP_NO_RTTI
113 
114 const void*
115 __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
116 {
117     return 0;
118 }
119 
120 #endif  // _LIBCPP_NO_RTTI
121 
122 void
123 declare_reachable(void*)
124 {
125 }
126 
127 void
128 declare_no_pointers(char*, size_t)
129 {
130 }
131 
132 void
133 undeclare_no_pointers(char*, size_t)
134 {
135 }
136 
137 pointer_safety
138 get_pointer_safety() _NOEXCEPT
139 {
140     return pointer_safety::relaxed;
141 }
142 
143 void*
144 __undeclare_reachable(void* p)
145 {
146     return p;
147 }
148 
149 void*
150 align(size_t alignment, size_t size, void*& ptr, size_t& space)
151 {
152     void* r = nullptr;
153     if (size <= space)
154     {
155         char* p1 = static_cast<char*>(ptr);
156         char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment);
157         ptrdiff_t d = p2 - p1;
158         if (d <= space - size)
159         {
160             r = p2;
161             ptr = r;
162             space -= d;
163         }
164     }
165     return r;
166 }
167 
168 _LIBCPP_END_NAMESPACE_STD
169