1 /** 2 Lightweight profiler library for c++ 3 Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin 4 5 Licensed under either of 6 * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) 7 * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) 8 at your option. 9 10 The MIT License 11 Permission is hereby granted, free of charge, to any person obtaining a copy 12 of this software and associated documentation files (the "Software"), to deal 13 in the Software without restriction, including without limitation the rights 14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 15 of the Software, and to permit persons to whom the Software is furnished 16 to do so, subject to the following conditions: 17 18 The above copyright notice and this permission notice shall be included in all 19 copies or substantial portions of the Software. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 22 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 26 USE OR OTHER DEALINGS IN THE SOFTWARE. 27 28 29 The Apache License, Version 2.0 (the "License"); 30 You may not use this file except in compliance with the License. 31 You may obtain a copy of the License at 32 33 http://www.apache.org/licenses/LICENSE-2.0 34 35 Unless required by applicable law or agreed to in writing, software 36 distributed under the License is distributed on an "AS IS" BASIS, 37 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 38 See the License for the specific language governing permissions and 39 limitations under the License. 40 41 **/ 42 43 #ifndef EASY_PROFILER_H 44 #define EASY_PROFILER_H 45 46 #include <easy/details/profiler_public_types.h> 47 48 #if defined ( __clang__ ) 49 # pragma clang diagnostic push 50 # pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 51 #endif 52 53 // 54 // BUILD_WITH_EASY_PROFILER is defined in CMakeLists.txt if your project is linked to easy_profiler. 55 // 56 57 // 58 // DISABLE_EASY_PROFILER may be defined manually in source-file before #include <easy/profiler.h> 59 // to disable profiler for certain source-file or project. 60 // 61 62 #if defined(BUILD_WITH_EASY_PROFILER) && !defined(DISABLE_EASY_PROFILER) 63 64 /** 65 \defgroup profiler EasyProfiler 66 */ 67 68 69 /** Indicates that EasyProfiler is used. 70 71 \ingroup profiler 72 */ 73 #define USING_EASY_PROFILER 74 75 76 // EasyProfiler core API: 77 78 /** Macro for beginning of a scoped block with custom name and color. 79 80 \code 81 #include <easy/profiler.h> 82 void foo() 83 { 84 // some code ... 85 86 EASY_BLOCK("Check something", profiler::OFF); // Disabled block (There is possibility to enable this block later via GUI) 87 if(something){ 88 EASY_BLOCK("Calling bar()"); // Block with default color 89 bar(); 90 } 91 else{ 92 EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block 93 baz(); 94 } 95 EASY_END_BLOCK; // End of "Check something" block (Even if "Check something" is disabled, this EASY_END_BLOCK will not end any other block). 96 97 EASY_BLOCK("Some another block", profiler::colors::Blue, profiler::ON_WITHOUT_CHILDREN); // Block with Blue color without 98 // some another code... 99 EASY_BLOCK("Calculate sum"); // This block will not be profiled because it's parent is ON_WITHOUT_CHILDREN 100 int sum = 0; 101 for (int i = 0; i < 10; ++i) 102 sum += i; 103 EASY_END_BLOCK; // End of "Calculate sum" block 104 } 105 \endcode 106 107 Block will be automatically completed by destructor. 108 109 \ingroup profiler 110 */ 111 # define EASY_BLOCK(name, ...)\ 112 EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(::profiler::extract_enable_flag(__VA_ARGS__),\ 113 EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name), __FILE__, __LINE__, ::profiler::BlockType::Block, ::profiler::extract_color(__VA_ARGS__),\ 114 ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ 115 ::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name));\ 116 ::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); 117 118 /** Macro for beginning of a non-scoped block with custom name and color. 119 120 You must end such block manually with EASY_END_BLOCK. 121 122 \code 123 #include <easy/profiler.h> 124 void foo() { 125 EASY_NONSCOPED_BLOCK("Callback"); // Begin block which would not be finished when function returns. 126 127 // some code ... 128 } 129 130 void bar() { 131 // some another code... 132 133 EASY_END_BLOCK; // This, as always, ends last opened block. You have to take care about blocks order by yourself. 134 } 135 136 void baz() { 137 foo(); // non-scoped block begins here 138 139 // some code... 140 141 bar(); // non-scoped block ends here 142 } 143 \endcode 144 145 Block will be automatically completed by destructor. 146 147 \ingroup profiler 148 */ 149 #define EASY_NONSCOPED_BLOCK(name, ...)\ 150 EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(::profiler::extract_enable_flag(__VA_ARGS__),\ 151 EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name), __FILE__, __LINE__, ::profiler::BlockType::Block, ::profiler::extract_color(__VA_ARGS__),\ 152 ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ 153 ::profiler::beginNonScopedBlock(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name)); 154 155 /** Macro for beginning of a block with function name and custom color. 156 157 \code 158 #include <easy/profiler.h> 159 void foo(){ 160 EASY_FUNCTION(); // Block with name="foo" and default color 161 //some code... 162 } 163 164 void bar(){ 165 EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar" 166 //some code... 167 } 168 169 void baz(){ 170 EASY_FUNCTION(profiler::FORCE_ON); // Force enabled block with name="baz" and default color (This block will be profiled even if it's parent is OFF_RECURSIVE) 171 // som code... 172 } 173 \endcode 174 175 Name of the block automatically created with function name. 176 177 \ingroup profiler 178 */ 179 # define EASY_FUNCTION(...) EASY_BLOCK(EASY_FUNC_NAME, ## __VA_ARGS__) 180 181 /** Macro for completion of last opened block explicitly. 182 183 \code 184 #include <easy/profiler.h> 185 int foo() 186 { 187 // some code ... 188 189 int sum = 0; 190 EASY_BLOCK("Calculating sum"); 191 for (int i = 0; i < 10; ++i){ 192 sum += i; 193 } 194 EASY_END_BLOCK; 195 196 // some antoher code here ... 197 198 return sum; 199 } 200 \endcode 201 202 \ingroup profiler 203 */ 204 # define EASY_END_BLOCK ::profiler::endBlock(); 205 206 /** Macro for creating event marker with custom name and color. 207 208 Event marker is a block with zero duration and special type. 209 210 \warning Event marker ends immidiately and calling EASY_END_BLOCK after EASY_EVENT 211 will end previously opened EASY_BLOCK or EASY_FUNCTION. 212 213 \ingroup profiler 214 */ 215 # define EASY_EVENT(name, ...)\ 216 EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ 217 ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ 218 __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__),\ 219 ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ 220 ::profiler::storeEvent(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name)); 221 222 /** Macro for enabling profiler. 223 224 \ingroup profiler 225 */ 226 # define EASY_PROFILER_ENABLE ::profiler::setEnabled(true); 227 228 /** Macro for disabling profiler. 229 230 \ingroup profiler 231 */ 232 # define EASY_PROFILER_DISABLE ::profiler::setEnabled(false); 233 234 /** Macro for current thread registration. 235 236 \note If this thread has been already registered then nothing happens. 237 238 \ingroup profiler 239 */ 240 # define EASY_THREAD(name)\ 241 EASY_THREAD_LOCAL static const char* EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = 0;\ 242 if (!EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__))\ 243 EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThread(name); 244 245 /** Macro for current thread registration and creating a thread guard object. 246 247 \note If this thread has been already registered then nothing happens. 248 249 \note Also creates thread guard which marks thread as "expired" on it's destructor 250 and creates "ThreadFinished" profiler event. 251 252 \ingroup profiler 253 */ 254 # define EASY_THREAD_SCOPE(name)\ 255 EASY_THREAD_LOCAL static const char* EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = 0;\ 256 ::profiler::ThreadGuard EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__);\ 257 if (!EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__))\ 258 EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThreadScoped(name,\ 259 EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__)); 260 261 /** Macro for main thread registration. 262 263 This is just for user's comfort. There is no difference for EasyProfiler GUI between different threads. 264 265 \ingroup profiler 266 */ 267 # define EASY_MAIN_THREAD EASY_THREAD("Main") 268 269 /** Enable or disable event tracing (context switch events). 270 271 \note Default value is controlled by EASY_OPTION_EVENT_TRACING_ENABLED macro. 272 273 \note Change will take effect on the next call to EASY_PROFILER_ENABLE. 274 275 \sa EASY_PROFILER_ENABLE, EASY_OPTION_EVENT_TRACING_ENABLED 276 277 \ingroup profiler 278 */ 279 # define EASY_SET_EVENT_TRACING_ENABLED(isEnabled) ::profiler::setEventTracingEnabled(isEnabled); 280 281 /** Set event tracing thread priority (low or normal). 282 283 Event tracing with low priority will affect your application performance much more less, but 284 it can be late to gather information about thread/process (thread could be finished to the moment 285 when event tracing thread will be awaken) and you will not see process name and process id 286 information in GUI for such threads. You will still be able to see all context switch events. 287 288 Event tracing with normal priority could gather more information about processes but potentially 289 it could affect performance as it has more work to do. Usually you will not notice any performance 290 breakdown, but if you care about that then you change set event tracing priority level to low. 291 292 \sa EASY_OPTION_LOW_PRIORITY_EVENT_TRACING 293 294 \ingroup profiler 295 */ 296 # define EASY_SET_LOW_PRIORITY_EVENT_TRACING(isLowPriority) ::profiler::setLowPriorityEventTracing(isLowPriority); 297 298 /** Macro for setting temporary log-file path for Unix event tracing system. 299 300 \note Default value is "/tmp/cs_profiling_info.log". 301 302 \ingroup profiler 303 */ 304 # define EASY_EVENT_TRACING_SET_LOG(filename) ::profiler::setContextSwitchLogFilename(filename); 305 306 /** Macro returning current path to the temporary log-file for Unix event tracing system. 307 308 \ingroup profiler 309 */ 310 # define EASY_EVENT_TRACING_LOG ::profiler::getContextSwitchLogFilename(); 311 312 // EasyProfiler settings: 313 314 /** If != 0 then EasyProfiler will measure time for blocks storage expansion. 315 If 0 then EasyProfiler will be compiled without blocks of code responsible 316 for measuring these events. 317 318 These are "EasyProfiler.ExpandStorage" blocks on a diagram. 319 320 \ingroup profiler 321 */ 322 # ifndef EASY_OPTION_MEASURE_STORAGE_EXPAND 323 # define EASY_OPTION_MEASURE_STORAGE_EXPAND 0 324 # endif 325 326 # if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 327 /** If true then "EasyProfiler.ExpandStorage" blocks are enabled by default and will be 328 writed to output file or translated over the net. 329 If false then you need to enable these blocks via GUI if you want to see them. 330 331 \ingroup profiler 332 */ 333 # ifndef EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON 334 # define EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON true 335 # endif 336 337 # endif // EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 338 339 /** If true then EasyProfiler event tracing is enabled by default 340 and will be turned on and off when you call profiler::setEnabled(). 341 Otherwise, it have to be turned on via GUI and then it will be 342 turned on/off with next calls of profiler::setEnabled(). 343 344 \ingroup profiler 345 */ 346 # ifndef EASY_OPTION_EVENT_TRACING_ENABLED 347 # define EASY_OPTION_EVENT_TRACING_ENABLED true 348 # endif 349 350 /** If true then EasyProfiler.ETW thread (Event tracing for Windows) will have low priority by default. 351 352 \sa EASY_SET_LOW_PRIORITY_EVENT_TRACING 353 354 \note You can always change priority level via GUI or API while profiling session is not launched. 355 You don't need to rebuild or restart your application for that. 356 357 \ingroup profiler 358 */ 359 # ifndef EASY_OPTION_LOW_PRIORITY_EVENT_TRACING 360 # define EASY_OPTION_LOW_PRIORITY_EVENT_TRACING true 361 # endif 362 363 364 /** If != 0 then EasyProfiler will print error messages into stderr. 365 Otherwise, no log messages will be printed. 366 367 \ingroup profiler 368 */ 369 # ifndef EASY_OPTION_LOG_ENABLED 370 # define EASY_OPTION_LOG_ENABLED 0 371 # endif 372 373 /** If != 0 then EasyProfiler will start listening thread immidiately on ProfileManager initialization. 374 375 \sa startListen 376 377 \ingroup profiler 378 */ 379 # ifndef EASY_OPTION_START_LISTEN_ON_STARTUP 380 # define EASY_OPTION_START_LISTEN_ON_STARTUP 0 381 # endif 382 383 #else // #ifdef BUILD_WITH_EASY_PROFILER 384 385 # define EASY_BLOCK(...) 386 # define EASY_NONSCOPED_BLOCK(...) 387 # define EASY_FUNCTION(...) 388 # define EASY_END_BLOCK 389 # define EASY_PROFILER_ENABLE 390 # define EASY_PROFILER_DISABLE 391 # define EASY_EVENT(...) 392 # define EASY_THREAD(...) 393 # define EASY_THREAD_SCOPE(...) 394 # define EASY_MAIN_THREAD 395 # define EASY_SET_EVENT_TRACING_ENABLED(isEnabled) 396 # define EASY_SET_LOW_PRIORITY_EVENT_TRACING(isLowPriority) 397 398 # ifndef _WIN32 399 # define EASY_EVENT_TRACING_SET_LOG(filename) 400 # define EASY_EVENT_TRACING_LOG "" 401 # endif 402 403 # ifndef EASY_OPTION_MEASURE_STORAGE_EXPAND 404 # define EASY_OPTION_MEASURE_STORAGE_EXPAND 0 405 # endif 406 407 # ifndef EASY_OPTION_EVENT_TRACING_ENABLED 408 # define EASY_OPTION_EVENT_TRACING_ENABLED false 409 # endif 410 411 # ifndef EASY_OPTION_LOW_PRIORITY_EVENT_TRACING 412 # define EASY_OPTION_LOW_PRIORITY_EVENT_TRACING true 413 # endif 414 415 # ifndef EASY_OPTION_LOG_ENABLED 416 # define EASY_OPTION_LOG_ENABLED 0 417 # endif 418 419 # ifndef EASY_OPTION_START_LISTEN_ON_STARTUP 420 # define EASY_OPTION_START_LISTEN_ON_STARTUP 0 421 # endif 422 423 #endif // #ifndef BUILD_WITH_EASY_PROFILER 424 425 # ifndef EASY_DEFAULT_PORT 426 # define EASY_DEFAULT_PORT 28077 427 # endif 428 429 /** Alias for EASY_PROFILER_ENABLE. 430 431 Added for clarification. 432 433 \sa EASY_PROFILER_ENABLE 434 435 \ingroup profiler 436 */ 437 #define EASY_START_CAPTURE EASY_PROFILER_ENABLE 438 439 /** Alias for EASY_PROFILER_DISABLE. 440 441 Added for clarification. 442 443 \sa EASY_PROFILER_DISABLE 444 445 \ingroup profiler 446 */ 447 #define EASY_STOP_CAPTURE EASY_PROFILER_DISABLE 448 449 ////////////////////////////////////////////////////////////////////////// 450 ////////////////////////////////////////////////////////////////////////// 451 452 namespace profiler { 453 454 EASY_CONSTEXPR uint16_t DEFAULT_PORT = EASY_DEFAULT_PORT; 455 456 ////////////////////////////////////////////////////////////////////// 457 // Core API 458 // Note: It is better to use macros defined above than a direct calls to API. 459 // But some API functions does not have macro wrappers... 460 461 #ifdef USING_EASY_PROFILER 462 extern "C" { 463 464 /** Returns current time in ticks. 465 466 You can use it if you want to store block explicitly. 467 468 \retval Current CPU time in ticks. 469 470 \ingroup profiler 471 */ 472 PROFILER_API timestamp_t currentTime(); 473 474 /** Convert ticks to nanoseconds. 475 476 \retval _ticks converted to nanoseconds. 477 478 \ingroup profiler 479 */ 480 PROFILER_API timestamp_t toNanoseconds(timestamp_t _ticks); 481 482 /** Convert ticks to microseconds. 483 484 \retval _ticks converted to microseconds. 485 486 \ingroup profiler 487 */ 488 PROFILER_API timestamp_t toMicroseconds(timestamp_t _ticks); 489 490 /** Registers static description of a block. 491 492 It is general information which is common for all such blocks. 493 Includes color, block type (see BlockType), file-name, line-number, compile-time name of a block and enable-flag. 494 495 \note This API function is used by EASY_EVENT, EASY_BLOCK, EASY_FUNCTION macros. 496 There is no need to invoke this function explicitly. 497 498 \retval Pointer to registered block description. 499 500 \ingroup profiler 501 */ 502 PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _compiletimeName, const char* _filename, int _line, block_type_t _block_type, color_t _color, bool _copyName = false); 503 504 /** Stores event in the blocks list. 505 506 An event ends instantly and has zero duration. 507 508 \note There is no need to invoke this function explicitly - use EASY_EVENT macro instead. 509 510 \param _desc Reference to the previously registered description. 511 \param _runtimeName Standard zero-terminated string which will be copied to the events buffer. 512 513 \note _runtimeName must be an empty string ("") if you do not want to set name to the event at run-time. 514 515 \ingroup profiler 516 */ 517 PROFILER_API void storeEvent(const BaseBlockDescriptor* _desc, const char* _runtimeName = ""); 518 519 /** Stores block explicitly in the blocks list. 520 521 Use this function for additional flexibility if you want to set block duration manually. 522 523 \param _desc Reference to the previously registered description. 524 \param _runtimeName Standard zero-terminated string which will be copied to the events buffer. 525 \param _beginTime begin time of the block 526 \param _endTime end time of the block 527 528 \note _runtimeName must be an empty string ("") if you do not want to set name to the block at run-time. 529 530 \ingroup profiler 531 */ 532 PROFILER_API void storeBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName, timestamp_t _beginTime, timestamp_t _endTime); 533 534 /** Begins scoped block. 535 536 \ingroup profiler 537 */ 538 PROFILER_API void beginBlock(Block& _block); 539 540 /** Begins non-scoped block. 541 542 \param _desc Reference to the previously registered description (see registerDescription). 543 \param _runtimeName Standard zero-terminated string which will be copied to the block buffer when block will end. 544 545 \note There is no need to invoke this function explicitly - use EASY_NONSCOPED_BLOCK macro instead. 546 EASY_NONSCOPED_BLOCK macro could be used for higher flexibility if you have to begin block in one 547 function and end it in another one. 548 549 \note _runtimeName must be an empty string ("") if you do not want to set name to the block at run-time. 550 \note _runtimeName is copied only when block ends so you must ensure it's validity until block end. 551 552 \warning You have to end this block explicitly. 553 554 \ingroup profiler 555 */ 556 PROFILER_API void beginNonScopedBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName = ""); 557 558 /** Ends last started block. 559 560 Use this only if you want to finish block explicitly. 561 562 \ingroup profiler 563 */ 564 PROFILER_API void endBlock(); 565 566 /** Enable or disable profiler. 567 568 AKA start or stop profiling (capturing blocks). 569 570 \ingroup profiler 571 */ 572 PROFILER_API void setEnabled(bool _isEnable); 573 PROFILER_API bool isEnabled(); 574 575 /** Save all gathered blocks into file. 576 577 \note This also disables profiler. 578 579 \retval Number of saved blocks. If 0 then nothing was profiled or an error occured. 580 581 \ingroup profiler 582 */ 583 PROFILER_API uint32_t dumpBlocksToFile(const char* _filename); 584 585 /** Register current thread and give it a name. 586 587 Also creates a scoped ThreadGuard which would unregister thread on it's destructor. 588 This helps for memory management while using an old compiler whitout thread_local support. 589 590 \note Only first call of registerThread() for the current thread will have an effect. 591 592 \note Use this function if you want to build your source code with an old compiler (MSVC < 2013, GCC < 4.8, Clang < 3.3). 593 Otherwise there is no need in this function because a thread_local ThreadGuard created inside. 594 595 \retval Registered name of the thread. It may differ from _name if the thread was registered before. 596 597 \sa registerThread, ThreadGuard 598 599 \ingroup profiler 600 */ 601 PROFILER_API const char* registerThreadScoped(const char* _name, ThreadGuard&); 602 603 /** Register current thread and give it a name. 604 605 \note Only first call of registerThread() for the current thread will have an effect. 606 607 \retval Registered name of the thread. It may differ from _name if the thread was registered before. 608 609 \ingroup profiler 610 */ 611 PROFILER_API const char* registerThread(const char* _name); 612 613 /** Enable or disable event tracing. 614 615 \note This change will take an effect on the next call of setEnabled(true); 616 617 \sa setEnabled, EASY_SET_EVENT_TRACING_ENABLED 618 619 \ingroup profiler 620 */ 621 PROFILER_API void setEventTracingEnabled(bool _isEnable); 622 PROFILER_API bool isEventTracingEnabled(); 623 624 /** Set event tracing thread priority (low or normal). 625 626 \note This change will take effect on the next call of setEnabled(true); 627 628 \sa setEnabled, EASY_SET_LOW_PRIORITY_EVENT_TRACING 629 630 \ingroup profiler 631 */ 632 PROFILER_API void setLowPriorityEventTracing(bool _isLowPriority); 633 PROFILER_API bool isLowPriorityEventTracing(); 634 635 /** Set temporary log-file path for Unix event tracing system. 636 637 \note Default value is "/tmp/cs_profiling_info.log". 638 639 \ingroup profiler 640 */ 641 PROFILER_API void setContextSwitchLogFilename(const char* _name); 642 643 /** Returns current path to the temporary log-file for Unix event tracing system. 644 645 \ingroup profiler 646 */ 647 PROFILER_API const char* getContextSwitchLogFilename(); 648 649 /** Start listening for network commands. 650 651 Launches a separate listening thread which would listen to the network commands (start, stop, etc.). 652 The listening thread sends all profiled blocks via network after receiving network command 'stop'. 653 654 \ingroup profiler 655 */ 656 PROFILER_API void startListen(uint16_t _port = ::profiler::DEFAULT_PORT); 657 658 /** Stops listening thread. 659 660 \note This would be invoked automatically on application exit. 661 662 \note Does not send any messages to the network, just stops thread. 663 664 \ingroup profiler 665 */ 666 PROFILER_API void stopListen(); 667 668 /** Check if listening thread launched. 669 670 \ingroup profiler 671 */ 672 PROFILER_API bool isListening(); 673 674 /** Returns current major version. 675 676 \ingroup profiler 677 */ 678 PROFILER_API uint8_t versionMajor(); 679 680 /** Returns current minor version. 681 682 \ingroup profiler 683 */ 684 PROFILER_API uint8_t versionMinor(); 685 686 /** Returns current version patch. 687 688 \ingroup profiler 689 */ 690 PROFILER_API uint16_t versionPatch(); 691 692 /** Returns current version in 32-bit integer format. 693 694 \note Format is: 0x MAJ-MAJ MIN-MIN PATCH-PATCH-PATCH-PATCH 695 For example v1.3.0 is: 0x01030000 696 697 \ingroup profiler 698 */ 699 PROFILER_API uint32_t version(); 700 701 /** Returns current version string. 702 703 Example: "v1.3.0" 704 705 \ingroup profiler 706 */ 707 PROFILER_API const char* versionName(); 708 709 /** Returns true if current thread has been marked as Main. 710 Otherwise, returns false. 711 712 \ingroup profiler 713 */ 714 PROFILER_API bool isMainThread(); 715 716 /** Returns last frame duration for current thread. 717 718 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 719 720 \ingroup profiler 721 */ 722 PROFILER_API timestamp_t this_thread_frameTime(Duration _durationCast = ::profiler::MICROSECONDS); 723 724 /** Returns local max of frame duration for current thread. 725 726 Local max is maximum frame duration since last frameTimeLocalMax() call. 727 728 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 729 730 \ingroup profiler 731 */ 732 PROFILER_API timestamp_t this_thread_frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS); 733 734 /** Returns local average of frame duration for current thread. 735 736 Local average is average frame duration since last frameTimeLocalAvg() call. 737 738 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 739 740 \ingroup profiler 741 */ 742 PROFILER_API timestamp_t this_thread_frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS); 743 744 /** Returns last frame duration for main thread. 745 746 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 747 748 \ingroup profiler 749 */ 750 PROFILER_API timestamp_t main_thread_frameTime(Duration _durationCast = ::profiler::MICROSECONDS); 751 752 /** Returns local max of frame duration for main thread. 753 754 Local max is maximum frame duration since last frameTimeLocalMax() call. 755 756 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 757 758 \ingroup profiler 759 */ 760 PROFILER_API timestamp_t main_thread_frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS); 761 762 /** Returns local average of frame duration for main thread. 763 764 Local average is average frame duration since last frameTimeLocalAvg() call. 765 766 \param _durationCast desired duration units (could be cpu-ticks or microseconds) 767 768 \ingroup profiler 769 */ 770 PROFILER_API timestamp_t main_thread_frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS); 771 772 } 773 #else currentTime()774 inline timestamp_t currentTime() { return 0; } toNanoseconds(timestamp_t)775 inline timestamp_t toNanoseconds(timestamp_t) { return 0; } toMicroseconds(timestamp_t)776 inline timestamp_t toMicroseconds(timestamp_t) { return 0; } 777 inline const BaseBlockDescriptor* registerDescription(EasyBlockStatus, const char*, const char*, const char*, int, block_type_t, color_t, bool = false) 778 { return reinterpret_cast<const BaseBlockDescriptor*>(0xbad); } endBlock()779 inline void endBlock() { } setEnabled(bool)780 inline void setEnabled(bool) { } isEnabled()781 inline bool isEnabled() { return false; } 782 inline void storeEvent(const BaseBlockDescriptor*, const char* = "") { } storeBlock(const BaseBlockDescriptor *,const char *,timestamp_t,timestamp_t)783 inline void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { } beginBlock(Block &)784 inline void beginBlock(Block&) { } 785 inline void beginNonScopedBlock(const BaseBlockDescriptor*, const char* = "") { } dumpBlocksToFile(const char *)786 inline uint32_t dumpBlocksToFile(const char*) { return 0; } registerThreadScoped(const char *,ThreadGuard &)787 inline const char* registerThreadScoped(const char*, ThreadGuard&) { return ""; } registerThread(const char *)788 inline const char* registerThread(const char*) { return ""; } setEventTracingEnabled(bool)789 inline void setEventTracingEnabled(bool) { } isEventTracingEnabled()790 inline bool isEventTracingEnabled() { return false; } setLowPriorityEventTracing(bool)791 inline void setLowPriorityEventTracing(bool) { } isLowPriorityEventTracing()792 inline bool isLowPriorityEventTracing() { return false; } setContextSwitchLogFilename(const char *)793 inline void setContextSwitchLogFilename(const char*) { } getContextSwitchLogFilename()794 inline const char* getContextSwitchLogFilename() { return ""; } 795 inline void startListen(uint16_t = ::profiler::DEFAULT_PORT) { } stopListen()796 inline void stopListen() { } isListening()797 inline bool isListening() { return false; } versionMajor()798 inline uint8_t versionMajor() { return 0; } versionMinor()799 inline uint8_t versionMinor() { return 0; } versionPatch()800 inline uint16_t versionPatch() { return 0; } version()801 inline uint32_t version() { return 0; } versionName()802 inline const char* versionName() { return "v0.0.0_disabled"; } isMainThread()803 inline bool isMainThread() { return false; } 804 inline timestamp_t this_thread_frameTime(Duration = ::profiler::MICROSECONDS) { return 0; } 805 inline timestamp_t this_thread_frameTimeLocalMax(Duration = ::profiler::MICROSECONDS) { return 0; } 806 inline timestamp_t this_thread_frameTimeLocalAvg(Duration = ::profiler::MICROSECONDS) { return 0; } 807 inline timestamp_t main_thread_frameTime(Duration = ::profiler::MICROSECONDS) { return 0; } 808 inline timestamp_t main_thread_frameTimeLocalMax(Duration = ::profiler::MICROSECONDS) { return 0; } 809 inline timestamp_t main_thread_frameTimeLocalAvg(Duration = ::profiler::MICROSECONDS) { return 0; } 810 #endif 811 812 /** API functions binded to current thread. 813 814 \ingroup profiler 815 */ 816 namespace this_thread { 817 registrate(const char * _name)818 inline const char* registrate(const char* _name) { 819 return ::profiler::registerThread(_name); 820 } 821 registrate(const char * _name,ThreadGuard & _threadGuard)822 inline const char* registrate(const char* _name, ThreadGuard& _threadGuard) { 823 return ::profiler::registerThreadScoped(_name, _threadGuard); 824 } 825 826 inline timestamp_t frameTime(Duration _durationCast = ::profiler::MICROSECONDS) { 827 return ::profiler::this_thread_frameTime(_durationCast); 828 } 829 830 inline timestamp_t frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS) { 831 return ::profiler::this_thread_frameTimeLocalMax(_durationCast); 832 } 833 834 inline timestamp_t frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS) { 835 return ::profiler::this_thread_frameTimeLocalAvg(_durationCast); 836 } 837 isMain()838 inline bool isMain() { 839 return ::profiler::isMainThread(); 840 } 841 842 } // END of namespace this_thread. 843 844 /** API functions binded to main thread. 845 846 Could be called from any thread. 847 848 \ingroup profiler 849 */ 850 namespace main_thread { 851 852 inline timestamp_t frameTime(Duration _durationCast = ::profiler::MICROSECONDS) { 853 return ::profiler::main_thread_frameTime(_durationCast); 854 } 855 856 inline timestamp_t frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS) { 857 return ::profiler::main_thread_frameTimeLocalMax(_durationCast); 858 } 859 860 inline timestamp_t frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS) { 861 return ::profiler::main_thread_frameTimeLocalAvg(_durationCast); 862 } 863 864 /** Always returns true. 865 */ isMain()866 inline EASY_CONSTEXPR_FCN bool isMain() { 867 return true; 868 } 869 870 } // END of namespace main_thread. 871 872 /** Alias for isEnabled(). 873 874 Added for clarification. 875 876 \sa isEnabled 877 878 \ingroup profiler 879 */ isCapturing()880 EASY_FORCE_INLINE bool isCapturing() { return isEnabled(); } 881 882 /** Alias for EASY_PROFILER_ENABLE. 883 884 Added for clarification. 885 886 \sa EASY_PROFILER_ENABLE 887 888 \ingroup profiler 889 */ startCapture()890 EASY_FORCE_INLINE void startCapture() { EASY_PROFILER_ENABLE; } 891 892 /** Alias for EASY_PROFILER_DISABLE. 893 894 Added for clarification. 895 896 \sa EASY_PROFILER_DISABLE 897 898 \ingroup profiler 899 */ stopCapture()900 EASY_FORCE_INLINE void stopCapture() { EASY_PROFILER_DISABLE; } 901 902 ////////////////////////////////////////////////////////////////////// 903 904 } // END of namespace profiler. 905 906 #if defined ( __clang__ ) 907 # pragma clang diagnostic pop 908 #endif 909 910 #endif // EASY_PROFILER_H 911