1#include <base/bind.h> 2#include <base/logging.h> 3#include <base/run_loop.h> 4#include <base/threading/thread.h> 5#include <gmock/gmock.h> 6#include <gtest/gtest.h> 7#include <unistd.h> 8#include <chrono> 9#include <iostream> 10 11#include "osi/include/fixed_queue.h" 12#include "osi/include/thread.h" 13 14#define NUM_MESSAGES_TO_SEND 1000000 15 16base::MessageLoop* message_loop; 17base::RunLoop* run_loop; 18thread_t* thread; 19 20volatile static int counter = 0; 21volatile bool loop_ready = false; 22 23void set_loop_ready() { loop_ready = true; } 24 25void callback(fixed_queue_t* queue, void* data) { 26 if (queue != nullptr) { 27 fixed_queue_dequeue(queue); 28 } 29 30 counter++; 31} 32 33void run_message_loop(void* UNUSED) { 34 message_loop = new base::MessageLoop(); 35 run_loop = new base::RunLoop(); 36 37 message_loop->task_runner()->PostTask(FROM_HERE, base::Bind(&set_loop_ready)); 38 39 run_loop->Run(); 40 41 delete message_loop; 42 message_loop = nullptr; 43 44 delete run_loop; 45 run_loop = nullptr; 46} 47 48class PerformanceTest : public testing::Test { 49 public: 50 fixed_queue_t* bt_msg_queue; 51 52 void SetUp() override { 53 counter = 0; 54 55 bt_msg_queue = fixed_queue_new(SIZE_MAX); 56 thread = thread_new("performance test thread"); 57 thread_post(thread, run_message_loop, nullptr); 58 } 59 60 void TearDown() override { 61 fixed_queue_free(bt_msg_queue, NULL); 62 bt_msg_queue = nullptr; 63 64 thread_free(thread); 65 thread = nullptr; 66 } 67}; 68 69TEST_F(PerformanceTest, message_loop_speed_test) { 70 loop_ready = false; 71 int test_data = 0; 72 73 std::chrono::steady_clock::time_point start_time = 74 std::chrono::steady_clock::now(); 75 while (!loop_ready) { 76 } 77 for (int i = 0; i < NUM_MESSAGES_TO_SEND; i++) { 78 fixed_queue_enqueue(bt_msg_queue, (void*)&test_data); 79 message_loop->task_runner()->PostTask( 80 FROM_HERE, base::Bind(&callback, bt_msg_queue, nullptr)); 81 } 82 83 message_loop->task_runner()->PostTask(FROM_HERE, 84 run_loop->QuitWhenIdleClosure()); 85 while (counter < NUM_MESSAGES_TO_SEND) { 86 } 87 88 std::chrono::steady_clock::time_point end_time = 89 std::chrono::steady_clock::now(); 90 std::chrono::milliseconds duration = 91 std::chrono::duration_cast<std::chrono::milliseconds>(end_time - 92 start_time); 93 94 LOG(INFO) << "Message loop took " << duration.count() << "ms for " 95 << NUM_MESSAGES_TO_SEND << " messages"; 96} 97 98TEST_F(PerformanceTest, reactor_thread_speed_test) { 99 counter = 0; 100 int test_data = 0; 101 102 thread = thread_new("queue performance test thread"); 103 bt_msg_queue = fixed_queue_new(SIZE_MAX); 104 fixed_queue_register_dequeue(bt_msg_queue, thread_get_reactor(thread), 105 callback, NULL); 106 107 std::chrono::steady_clock::time_point start_time = 108 std::chrono::steady_clock::now(); 109 for (int i = 0; i < NUM_MESSAGES_TO_SEND; i++) { 110 fixed_queue_enqueue(bt_msg_queue, (void*)&test_data); 111 } 112 113 while (counter < NUM_MESSAGES_TO_SEND) { 114 }; 115 116 std::chrono::steady_clock::time_point end_time = 117 std::chrono::steady_clock::now(); 118 std::chrono::milliseconds duration = 119 std::chrono::duration_cast<std::chrono::milliseconds>(end_time - 120 start_time); 121 122 LOG(INFO) << "Reactor thread took " << duration.count() << "ms for " 123 << NUM_MESSAGES_TO_SEND << " messages"; 124 125 fixed_queue_free(bt_msg_queue, NULL); 126 bt_msg_queue = nullptr; 127 128 thread_free(thread); 129 thread = nullptr; 130} 131