1 | //
|
---|
2 | // detail/thread_info_base.hpp
|
---|
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
---|
4 | //
|
---|
5 | // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
---|
6 | //
|
---|
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
---|
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
---|
9 | //
|
---|
10 |
|
---|
11 | #ifndef BOOST_ASIO_DETAIL_THREAD_INFO_BASE_HPP
|
---|
12 | #define BOOST_ASIO_DETAIL_THREAD_INFO_BASE_HPP
|
---|
13 |
|
---|
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
---|
15 | # pragma once
|
---|
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
---|
17 |
|
---|
18 | #include <climits>
|
---|
19 | #include <cstddef>
|
---|
20 | #include <boost/asio/detail/noncopyable.hpp>
|
---|
21 |
|
---|
22 | #include <boost/asio/detail/push_options.hpp>
|
---|
23 |
|
---|
24 | namespace boost {
|
---|
25 | namespace asio {
|
---|
26 | namespace detail {
|
---|
27 |
|
---|
28 | class thread_info_base
|
---|
29 | : private noncopyable
|
---|
30 | {
|
---|
31 | public:
|
---|
32 | struct default_tag
|
---|
33 | {
|
---|
34 | enum { mem_index = 0 };
|
---|
35 | };
|
---|
36 |
|
---|
37 | struct awaitee_tag
|
---|
38 | {
|
---|
39 | enum { mem_index = 1 };
|
---|
40 | };
|
---|
41 |
|
---|
42 | thread_info_base()
|
---|
43 | {
|
---|
44 | for (int i = 0; i < max_mem_index; ++i)
|
---|
45 | reusable_memory_[i] = 0;
|
---|
46 | }
|
---|
47 |
|
---|
48 | ~thread_info_base()
|
---|
49 | {
|
---|
50 | for (int i = 0; i < max_mem_index; ++i)
|
---|
51 | if (reusable_memory_[i])
|
---|
52 | ::operator delete(reusable_memory_[i]);
|
---|
53 | }
|
---|
54 |
|
---|
55 | static void* allocate(thread_info_base* this_thread, std::size_t size)
|
---|
56 | {
|
---|
57 | return allocate(default_tag(), this_thread, size);
|
---|
58 | }
|
---|
59 |
|
---|
60 | static void deallocate(thread_info_base* this_thread,
|
---|
61 | void* pointer, std::size_t size)
|
---|
62 | {
|
---|
63 | deallocate(default_tag(), this_thread, pointer, size);
|
---|
64 | }
|
---|
65 |
|
---|
66 | template <typename Purpose>
|
---|
67 | static void* allocate(Purpose, thread_info_base* this_thread,
|
---|
68 | std::size_t size)
|
---|
69 | {
|
---|
70 | std::size_t chunks = (size + chunk_size - 1) / chunk_size;
|
---|
71 |
|
---|
72 | if (this_thread && this_thread->reusable_memory_[Purpose::mem_index])
|
---|
73 | {
|
---|
74 | void* const pointer = this_thread->reusable_memory_[Purpose::mem_index];
|
---|
75 | this_thread->reusable_memory_[Purpose::mem_index] = 0;
|
---|
76 |
|
---|
77 | unsigned char* const mem = static_cast<unsigned char*>(pointer);
|
---|
78 | if (static_cast<std::size_t>(mem[0]) >= chunks)
|
---|
79 | {
|
---|
80 | mem[size] = mem[0];
|
---|
81 | return pointer;
|
---|
82 | }
|
---|
83 |
|
---|
84 | ::operator delete(pointer);
|
---|
85 | }
|
---|
86 |
|
---|
87 | void* const pointer = ::operator new(chunks * chunk_size + 1);
|
---|
88 | unsigned char* const mem = static_cast<unsigned char*>(pointer);
|
---|
89 | # pragma warning( push ) ///@@@Boostilonchenkorrekturen.Michael Soliman.2018-04-10.///@@@C6386-Verwirrung beim Schreiben von weniger Daten als erlaubt.Michael Soliman.2018-03-27.: warning C6386: Buffer overrun while writing to 'mem': the writable size is 'size+1' bytes, but 'size' bytes might be written...///@@@Boostilonchenkorrekturen.Michael Soliman.2018-04-10.
|
---|
90 | # pragma warning(disable:6386 ) ///@@@Boostilonchenkorrekturen.Michael Soliman.2018-04-10.///@@@C6386-Verwirrung beim Schreiben von weniger Daten als erlaubt.Michael Soliman.2018-03-27.: warning C6386: Buffer overrun while writing to 'mem': the writable size is 'size+1' bytes, but 'size' bytes might be written...
|
---|
91 | mem[size] = (chunks <= UCHAR_MAX) ? static_cast<unsigned char>(chunks) : 0;;;///@@@Boostilonchenkorrekturen.Michael Soliman.2018-04-10.///@@@C6386-Verwirrung beim Schreiben von weniger Daten als erlaubt.Michael Soliman.2018-03-27.: warning C6386: Buffer overrun while writing to 'mem': the writable size is 'size+1' bytes, but 'size' bytes might be written..
|
---|
92 | # pragma warning( pop ) ///@@@Boostilonchenkorrekturen.Michael Soliman.2018-04-10.///@@@C6386-Verwirrung beim Schreiben von weniger Daten als erlaubt.Michael Soliman.2018-03-27.: warning C6386: Buffer overrun while writing to 'mem': the writable size is 'size+1' bytes, but 'size' bytes might be written....
|
---|
93 | return pointer;
|
---|
94 | }
|
---|
95 |
|
---|
96 | template <typename Purpose>
|
---|
97 | static void deallocate(Purpose, thread_info_base* this_thread,
|
---|
98 | void* pointer, std::size_t size)
|
---|
99 | {
|
---|
100 | if (size <= chunk_size * UCHAR_MAX)
|
---|
101 | {
|
---|
102 | if (this_thread && this_thread->reusable_memory_[Purpose::mem_index] == 0)
|
---|
103 | {
|
---|
104 | unsigned char* const mem = static_cast<unsigned char*>(pointer);
|
---|
105 | mem[0] = mem[size];
|
---|
106 | this_thread->reusable_memory_[Purpose::mem_index] = pointer;
|
---|
107 | return;
|
---|
108 | }
|
---|
109 | }
|
---|
110 |
|
---|
111 | ::operator delete(pointer);
|
---|
112 | }
|
---|
113 |
|
---|
114 | private:
|
---|
115 | enum { chunk_size = 4 };
|
---|
116 | enum { max_mem_index = 2 };
|
---|
117 | void* reusable_memory_[max_mem_index];
|
---|
118 | };
|
---|
119 |
|
---|
120 | } // namespace detail
|
---|
121 | } // namespace asio
|
---|
122 | } // namespace boost
|
---|
123 |
|
---|
124 | #include <boost/asio/detail/pop_options.hpp>
|
---|
125 |
|
---|
126 | #endif // BOOST_ASIO_DETAIL_THREAD_INFO_BASE_HPP
|
---|