1+ /* *
2+ * Copyright (c) 2025, Timothy Stack
3+ *
4+ * All rights reserved.
5+ *
6+ * Redistribution and use in source and binary forms, with or without
7+ * modification, are permitted provided that the following conditions are met:
8+ *
9+ * * Redistributions of source code must retain the above copyright notice, this
10+ * list of conditions and the following disclaimer.
11+ * * Redistributions in binary form must reproduce the above copyright notice,
12+ * this list of conditions and the following disclaimer in the documentation
13+ * and/or other materials provided with the distribution.
14+ * * Neither the name of Timothy Stack nor the names of its contributors
15+ * may be used to endorse or promote products derived from this software
16+ * without specific prior written permission.
17+ *
18+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+ */
29+
30+ #ifndef lnav_distributed_slice
31+ #define lnav_distributed_slice
32+
33+ #include < vector>
34+
35+ #define DS_STRINGIZE (A ) #A
36+
37+ #if defined(__APPLE__)
38+ # define DIST_SLICE (id ) \
39+ __attribute__ ((used, \
40+ section (" __DATA,__ds_" DS_STRINGIZE ( \
41+ id) ",regular,no_dead_strip")))
42+ # define DIST_SLICE_BEGIN (id ) \
43+ __asm (" section$start$__DATA$__ds_" DS_STRINGIZE (id))
44+ # define DIST_SLICE_END (id ) \
45+ __asm (" section$end$__DATA$__ds_" DS_STRINGIZE (id))
46+ #else
47+ # define DIST_SLICE (id ) \
48+ __attribute__ ((used, section(" ds_" DS_STRINGIZE (id))))
49+ # define DIST_SLICE_BEGIN (id ) __asm(" __start_ds_" DS_STRINGIZE (id))
50+ # define DIST_SLICE_END (id ) __asm(" __stop_ds_" DS_STRINGIZE (id))
51+ #endif
52+
53+ template <typename T>
54+ struct dist_slice_container {
55+ using iterator = T*;
56+ using const_iterator = const T*;
57+
58+ constexpr dist_slice_container (iterator start, iterator end)
59+ : ds_start(start), ds_end(end)
60+ {
61+ }
62+
63+ constexpr iterator begin () { return this ->ds_start ; }
64+
65+ constexpr const_iterator begin () const { return this ->ds_start ; }
66+
67+ constexpr iterator end () { return this ->ds_end ; }
68+
69+ constexpr const_iterator end () const { return this ->ds_end ; }
70+
71+ size_t size () const { return this ->ds_end - this ->ds_start ; }
72+
73+ template <typename U>
74+ struct slice_indexed_array {
75+ using iterator = typename std::vector<U>::iterator;
76+
77+ explicit slice_indexed_array (const dist_slice_container& slices)
78+ : sia_slices(slices), sia_array(std::vector<U>(slices.size()))
79+ {
80+ }
81+
82+ U& operator [](const T* slice)
83+ {
84+ auto index = std::distance (this ->sia_slices .begin (), slice);
85+ return this ->sia_array [index];
86+ }
87+
88+ const U& operator [](const T* slice) const
89+ {
90+ auto index = std::distance (this ->sia_slices .begin (), slice);
91+ return this ->sia_array [index];
92+ }
93+
94+ iterator begin ()
95+ {
96+ return this ->sia_array .begin ();
97+ }
98+
99+ iterator end ()
100+ {
101+ return this ->sia_array .end ();
102+ }
103+
104+ void clear ()
105+ {
106+ for (auto & elem : this ->sia_array ) {
107+ elem.clear ();
108+ }
109+ }
110+
111+ private:
112+ const dist_slice_container& sia_slices;
113+ std::vector<U> sia_array;
114+ };
115+
116+ template <typename U>
117+ slice_indexed_array<U> create_array_indexed_by () const
118+ {
119+ return slice_indexed_array<U>(*this );
120+ }
121+
122+ private:
123+ iterator ds_start;
124+ iterator ds_end;
125+ };
126+
127+ #define DIST_SLICE_CONTAINER (T, id ) \
128+ (+[]() -> auto { \
129+ extern T start DIST_SLICE_BEGIN (id); \
130+ extern T end DIST_SLICE_END (id); \
131+ \
132+ return dist_slice_container<T>(&start, &end); \
133+ })()
134+
135+ #endif
0 commit comments