MUDA
Loading...
Searching...
No Matches
logger_viewer.inl
1#include <muda/atomic.h>
2
3namespace muda
4{
5MUDA_INLINE MUDA_DEVICE LogProxy::LogProxy(LoggerViewer& viewer)
6 : m_viewer(&viewer)
7{
8 MUDA_KERNEL_ASSERT(m_viewer->m_buffer && m_viewer->m_meta_data,
9 "LoggerViewer is not initialized");
10 m_log_id = atomic_add(&(m_viewer->m_offset->log_id), 1u);
11}
12template <bool IsFmt>
13MUDA_INLINE MUDA_DEVICE LogProxy& LogProxy::push_string(const char* str)
14{
15 auto strlen = [](const char* s)
16 {
17 size_t len = 0;
18 while(*s++)
19 ++len;
20 return len;
21 };
22 auto size = strlen(str) + 1;
23
24 details::LoggerMetaData meta;
25 if constexpr(IsFmt)
26 {
27 meta.type = LoggerBasicType::FmtString;
28 }
29 else
30 {
31 meta.type = LoggerBasicType::String;
32 }
33 meta.size = size;
34 meta.id = m_log_id;
35 m_viewer->push_data(meta, str);
36 return *this;
37}
38
39template <typename T>
40MUDA_DEVICE void LogProxy::push_fmt_arg(const T& obj, LoggerFmtArg func)
41{
42 details::LoggerMetaData meta;
43 meta.type = LoggerBasicType::Object;
44 meta.size = sizeof(T);
45 meta.id = m_log_id;
46 meta.fmt_arg = func;
47 m_viewer->push_data(meta, &obj);
48}
49
50MUDA_INLINE MUDA_DEVICE bool LogProxy::push_data(const details::LoggerMetaData& meta,
51 const void* data)
52{
53 return m_viewer->push_data(meta, data);
54}
55
56MUDA_INLINE MUDA_DEVICE LogProxy& LogProxy::operator<<(const char* str)
57{
58 return push_string<false>(str);
59}
60
61template <typename T>
62MUDA_INLINE MUDA_DEVICE LogProxy LoggerViewer::operator<<(const T& t)
63{
64 auto p = LogProxy(*this);
65 p << t;
66 return p;
67}
68
69template <bool IsFmt>
70MUDA_INLINE MUDA_DEVICE LogProxy LoggerViewer::push_string(const char* str)
71{
72 auto p = LogProxy(*this);
73 p.push_string<IsFmt>(str);
74 return p;
75}
76
77MUDA_INLINE MUDA_DEVICE LogProxy LoggerViewer::operator<<(const char* s)
78{
79 auto p = LogProxy(*this);
80 p << s;
81 return p;
82}
83
84MUDA_INLINE MUDA_DEVICE uint32_t next_idx(uint32_t* data_offset, uint32_t size, uint32_t total_size)
85{
86
87 uint32_t old = *data_offset;
88 if(old + size >= total_size)
89 return ~0u;
90 uint32_t assumed;
91 do
92 {
93 assumed = old;
94 auto new_offset = old + size;
95 old = atomic_cas(data_offset, assumed, new_offset);
96 if(old + size >= total_size)
97 {
98 old = ~0u;
99 break;
100 }
101 } while(assumed != old);
102 return old;
103}
104
105MUDA_INLINE MUDA_DEVICE uint32_t LoggerViewer::next_meta_data_idx() const
106{
107 auto idx = next_idx(&(m_offset->meta_data_offset), 1u, m_meta_data_size);
108 if(idx == ~0u)
109 {
110 atomic_cas(&(m_offset->exceed_meta_data), 0u, 1u);
111 return ~0u;
112 }
113 return idx;
114}
115
116MUDA_INLINE MUDA_DEVICE uint32_t LoggerViewer::next_buffer_idx(uint32_t size) const
117{
118 auto idx = next_idx(&(m_offset->buffer_offset), size, m_buffer_size);
119 if(idx == ~0u)
120 {
121 atomic_cas(&(m_offset->exceed_buffer), 0u, 1u);
122 return ~0u;
123 }
124 return idx;
125}
126
127MUDA_INLINE MUDA_DEVICE bool LoggerViewer::push_data(details::LoggerMetaData meta,
128 const void* data)
129{
130 auto meta_idx = next_meta_data_idx();
131 if(meta_idx == ~0u)
132 {
133 MUDA_KERNEL_WARN_WITH_LOCATION(
134 "LoggerViewer: meta data is exceeded, "
135 "the content[id=%d] will be discarded.",
136 meta.id);
137 return false;
138 }
139 auto buffer_idx = next_buffer_idx(meta.size);
140 if(buffer_idx == ~0u)
141 {
142 meta.exceeded = true;
143 MUDA_KERNEL_WARN_WITH_LOCATION(
144 "LoggerViewer: log buffer is exceeded, "
145 "the content[id=%d] will be discarded.",
146 meta.id);
147
148 m_meta_data[meta_idx] = meta;
149 m_meta_data_id[meta_idx] = meta.id;
150 return false;
151 }
152 meta.offset = buffer_idx;
153 m_meta_data[meta_idx] = meta;
154 m_meta_data_id[meta_idx] = meta.id;
155 for(int i = 0; i < meta.size; ++i)
156 m_buffer[buffer_idx + i] = reinterpret_cast<const char*>(data)[i];
157 return true;
158}
159} // namespace muda