|
8 | 8 | #pragma once |
9 | 9 |
|
10 | 10 | #include <atomic> |
| 11 | +#include <cassert> |
11 | 12 | #include <cstdint> |
| 13 | +#include <cstring> |
12 | 14 | #include <memory> |
13 | 15 | #include <sstream> |
14 | 16 | #include <thread> |
@@ -306,6 +308,165 @@ struct finally { |
306 | 308 |
|
307 | 309 | } // namespace utils |
308 | 310 |
|
| 311 | +template <typename T> |
| 312 | +inline result_t addMetadata(trace_event_data_t *Event, const std::string &Key, |
| 313 | + const T &Data) { |
| 314 | + static_assert(std::is_trivially_copyable_v<T>, |
| 315 | + "T must be trivially copyable"); |
| 316 | + static_assert(!std::is_same_v<T, const char *>); |
| 317 | + |
| 318 | + const uint8_t Type = [] { |
| 319 | + if (std::is_same_v<bool, T>) { |
| 320 | + return static_cast<uint8_t>(metadata_type_t::boolean); |
| 321 | + } |
| 322 | + if (std::numeric_limits<T>::is_integer && |
| 323 | + std::numeric_limits<T>::is_signed) { |
| 324 | + return static_cast<uint8_t>(metadata_type_t::signed_integer); |
| 325 | + } |
| 326 | + if (std::numeric_limits<T>::is_integer && |
| 327 | + !std::numeric_limits<T>::is_signed) { |
| 328 | + return static_cast<uint8_t>(metadata_type_t::unsigned_integer); |
| 329 | + } |
| 330 | + if (std::numeric_limits<T>::is_specialized && |
| 331 | + !std::numeric_limits<T>::is_integer) { |
| 332 | + return static_cast<uint8_t>(metadata_type_t::floating); |
| 333 | + } |
| 334 | + |
| 335 | + return static_cast<uint8_t>(metadata_type_t::binary); |
| 336 | + }(); |
| 337 | + |
| 338 | + object_id_t Value = xptiRegisterObject(reinterpret_cast<const char *>(&Data), |
| 339 | + sizeof(Data), Type); |
| 340 | + return xptiAddMetadata(Event, Key.c_str(), Value); |
| 341 | +} |
| 342 | + |
| 343 | +template <> |
| 344 | +inline result_t addMetadata<std::string>(trace_event_data_t *Event, |
| 345 | + const std::string &Key, |
| 346 | + const std::string &Data) { |
| 347 | + const uint8_t Type = static_cast<uint8_t>(metadata_type_t::string); |
| 348 | + object_id_t Value = xptiRegisterObject(Data.c_str(), Data.size(), Type); |
| 349 | + return xptiAddMetadata(Event, Key.c_str(), Value); |
| 350 | +} |
| 351 | + |
| 352 | +template <> |
| 353 | +inline result_t addMetadata<const char *>(trace_event_data_t *Event, |
| 354 | + const std::string &Key, |
| 355 | + const char *const &Data) { |
| 356 | + const uint8_t Type = static_cast<uint8_t>(metadata_type_t::string); |
| 357 | + object_id_t Value = xptiRegisterObject(Data, strlen(Data), Type); |
| 358 | + return xptiAddMetadata(Event, Key.c_str(), Value); |
| 359 | +} |
| 360 | + |
| 361 | +template <typename T> |
| 362 | +inline std::pair<std::string_view, T> |
| 363 | +getMetadata(const metadata_t::value_type &MD) { |
| 364 | + static_assert(std::is_trivially_copyable<T>::value, |
| 365 | + "T must be trivially copyable"); |
| 366 | + |
| 367 | + object_data_t RawData = xptiLookupObject(MD.second); |
| 368 | + assert(RawData.size == sizeof(T)); |
| 369 | + |
| 370 | + T Value = *reinterpret_cast<const T *>(RawData.data); |
| 371 | + |
| 372 | + const char *Key = xptiLookupString(MD.first); |
| 373 | + |
| 374 | + return std::make_pair(std::string_view(Key), Value); |
| 375 | +} |
| 376 | + |
| 377 | +template <> |
| 378 | +inline std::pair<std::string_view, std::string> |
| 379 | +getMetadata(const metadata_t::value_type &MD) { |
| 380 | + object_data_t RawData = xptiLookupObject(MD.second); |
| 381 | + |
| 382 | + std::string Value(RawData.data, RawData.size); |
| 383 | + |
| 384 | + const char *Key = xptiLookupString(MD.first); |
| 385 | + |
| 386 | + return std::make_pair(std::string_view(Key), Value); |
| 387 | +} |
| 388 | + |
| 389 | +template <> |
| 390 | +inline std::pair<std::string_view, std::string_view> |
| 391 | +getMetadata(const metadata_t::value_type &MD) { |
| 392 | + object_data_t RawData = xptiLookupObject(MD.second); |
| 393 | + |
| 394 | + std::string_view Value(RawData.data, RawData.size); |
| 395 | + |
| 396 | + const char *Key = xptiLookupString(MD.first); |
| 397 | + |
| 398 | + return std::make_pair(std::string_view(Key), Value); |
| 399 | +} |
| 400 | + |
| 401 | +inline std::string readMetadata(const metadata_t::value_type &MD) { |
| 402 | + object_data_t RawData = xptiLookupObject(MD.second); |
| 403 | + |
| 404 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::binary)) { |
| 405 | + return std::string("Binary data, size: ") + std::to_string(RawData.size); |
| 406 | + } |
| 407 | + |
| 408 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::boolean)) { |
| 409 | + bool Value = *reinterpret_cast<const bool *>(RawData.data); |
| 410 | + return Value ? "true" : "false"; |
| 411 | + } |
| 412 | + |
| 413 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::signed_integer)) { |
| 414 | + if (RawData.size == 1) { |
| 415 | + auto I = *reinterpret_cast<const int8_t *>(RawData.data); |
| 416 | + return std::to_string(I); |
| 417 | + } |
| 418 | + if (RawData.size == 2) { |
| 419 | + auto I = *reinterpret_cast<const int16_t *>(RawData.data); |
| 420 | + return std::to_string(I); |
| 421 | + } |
| 422 | + if (RawData.size == 4) { |
| 423 | + auto I = *reinterpret_cast<const int32_t *>(RawData.data); |
| 424 | + return std::to_string(I); |
| 425 | + } |
| 426 | + if (RawData.size == 8) { |
| 427 | + auto I = *reinterpret_cast<const int64_t *>(RawData.data); |
| 428 | + return std::to_string(I); |
| 429 | + } |
| 430 | + } |
| 431 | + |
| 432 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::unsigned_integer)) { |
| 433 | + if (RawData.size == 1) { |
| 434 | + auto I = *reinterpret_cast<const uint8_t *>(RawData.data); |
| 435 | + return std::to_string(I); |
| 436 | + } |
| 437 | + if (RawData.size == 2) { |
| 438 | + auto I = *reinterpret_cast<const uint16_t *>(RawData.data); |
| 439 | + return std::to_string(I); |
| 440 | + } |
| 441 | + if (RawData.size == 4) { |
| 442 | + auto I = *reinterpret_cast<const uint32_t *>(RawData.data); |
| 443 | + return std::to_string(I); |
| 444 | + } |
| 445 | + if (RawData.size == 8) { |
| 446 | + auto I = *reinterpret_cast<const uint64_t *>(RawData.data); |
| 447 | + return std::to_string(I); |
| 448 | + } |
| 449 | + } |
| 450 | + |
| 451 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::floating)) { |
| 452 | + if (RawData.size == 4) { |
| 453 | + auto F = *reinterpret_cast<const float *>(RawData.data); |
| 454 | + return std::to_string(F); |
| 455 | + } |
| 456 | + if (RawData.size == 8) { |
| 457 | + auto F = *reinterpret_cast<const double *>(RawData.data); |
| 458 | + return std::to_string(F); |
| 459 | + } |
| 460 | + } |
| 461 | + |
| 462 | + if (RawData.type == static_cast<uint8_t>(metadata_type_t::string)) { |
| 463 | + return std::string(RawData.data, RawData.size); |
| 464 | + } |
| 465 | + |
| 466 | + return std::string("Unknown metadata type, size ") + |
| 467 | + std::to_string(RawData.size); |
| 468 | +} |
| 469 | + |
309 | 470 | namespace framework { |
310 | 471 | constexpr uint16_t signal = (uint16_t)xpti::trace_point_type_t::signal; |
311 | 472 | constexpr uint16_t graph_create = |
|
0 commit comments