3232#include " pendulum_control/pendulum_motor.hpp"
3333#include " pendulum_control/rtt_executor.hpp"
3434
35+
36+ static bool running = false ;
37+
3538// Initialize a malloc hook so we can show that no mallocs are made during real-time execution
3639
3740// / Declare a function pointer into which we will store the default malloc.
38- static void *(* prev_malloc_hook)(size_t , const void *);
41+ static void * (* prev_malloc_hook)(size_t , const void *);
3942
4043// Use pragma to ignore a warning for using __malloc_hook, which is deprecated (but still awesome).
4144#pragma GCC diagnostic push
@@ -51,28 +54,20 @@ static void *(*prev_malloc_hook)(size_t, const void *);
5154static void * testing_malloc (size_t size, const void * caller)
5255{
5356 (void )caller;
57+ /*
5458 // Maximum depth we are willing to traverse into the stack trace.
5559 static const int MAX_DEPTH = 2;
5660 // Instantiate a buffer to store the traced symbols.
5761 void * backtrace_buffer[MAX_DEPTH];
62+ */
63+ if (running) {
64+ throw std::runtime_error (" Called malloc during realtime execution phase!" );
65+ }
66+
5867 // Set the malloc implementation to the default malloc hook so that we can call it implicitly
5968 // to initialize a string, otherwise this function will loop infinitely.
6069 __malloc_hook = prev_malloc_hook;
61- // Backtrace and get the depth of the stack that we traversed.
62- int stack_depth = backtrace (backtrace_buffer, MAX_DEPTH);
63- // Format the symbols as human-readable strings if possible.
64- char ** function_names = backtrace_symbols (backtrace_buffer, stack_depth);
65- // The 0th level of the stack is not very useful; try printing the 1st level.
66- if (stack_depth > 1 ) {
67- printf (" malloc(%u) called from %s [%p]\n " ,
68- (unsigned )size, function_names[1 ], backtrace_buffer[1 ]);
69- } else {
70- // If the first level was unavailable, default to the 0th level.
71- printf (" malloc(%u) called from %s [%p]\n " ,
72- (unsigned )size, function_names[0 ], backtrace_buffer[0 ]);
73- }
74- // Release the string that was allocated for printing.
75- free (function_names);
70+
7671 // Execute the requested malloc.
7772 void * mem = malloc (size);
7873 // Set the malloc hook back to this function, so that we can intercept future mallocs.
@@ -177,7 +172,7 @@ int main(int argc, char * argv[])
177172
178173 // Create a lambda function to invoke the motor callback when a command is received.
179174 auto motor_subscribe_callback =
180- [&pendulum_motor](const pendulum_msgs::msg::JointCommand::SharedPtr msg) -> void
175+ [&pendulum_motor](pendulum_msgs::msg::JointCommand::ConstSharedPtr msg) -> void
181176 {
182177 pendulum_motor->on_command_message (msg);
183178 };
@@ -190,7 +185,7 @@ int main(int argc, char * argv[])
190185
191186 // Create a lambda function to invoke the controller callback when a command is received.
192187 auto controller_subscribe_callback =
193- [&pendulum_controller](const pendulum_msgs::msg::JointState::SharedPtr msg) -> void
188+ [&pendulum_controller](pendulum_msgs::msg::JointState::ConstSharedPtr msg) -> void
194189 {
195190 pendulum_controller->on_sensor_message (msg);
196191 };
@@ -207,14 +202,14 @@ int main(int argc, char * argv[])
207202
208203 // Create a lambda function to accept user input to command the pendulum
209204 auto controller_command_callback =
210- [&pendulum_controller](const pendulum_msgs::msg::JointCommand::SharedPtr msg) -> void
205+ [&pendulum_controller](pendulum_msgs::msg::JointCommand::ConstSharedPtr msg) -> void
211206 {
212207 pendulum_controller->on_pendulum_setpoint (msg);
213208 };
214209
215- auto setpoint_sub = controller_node->create_subscription <pendulum_msgs::msg::JointCommand>
216- ( " pendulum_setpoint" , qos_profile, controller_command_callback, nullptr , false ,
217- setpoint_msg_strategy);
210+ auto setpoint_sub = controller_node->create_subscription <pendulum_msgs::msg::JointCommand>(
211+ " pendulum_setpoint" , qos_profile, controller_command_callback, nullptr , false ,
212+ setpoint_msg_strategy);
218213
219214 // Initialize the logger publisher.
220215 auto logger_pub = controller_node->create_publisher <pendulum_msgs::msg::RttestResults>(
@@ -267,8 +262,8 @@ int main(int argc, char * argv[])
267262 auto controller_publisher_timer = controller_node->create_wall_timer
268263 (pendulum_controller->get_publish_period (), controller_publish_callback);
269264 // Add a timer to enable regular publication of results messages.
270- auto logger_publisher_timer = controller_node->create_wall_timer
271- ( logger_publisher_period, logger_publish_callback);
265+ auto logger_publisher_timer = controller_node->create_wall_timer (
266+ logger_publisher_period, logger_publish_callback);
272267
273268 // Set the priority of this thread to the maximum safe value, and set its scheduling policy to a
274269 // deterministic (real-time safe) algorithm, round robin.
@@ -291,6 +286,7 @@ int main(int argc, char * argv[])
291286 // End initialization phase
292287
293288 // Execution phase
289+ running = true ;
294290
295291 // Unlike the default SingleThreadedExecutor::spin function, RttExecutor::spin runs in
296292 // bounded time (for as many iterations as specified in the rttest parameters).
@@ -301,6 +297,8 @@ int main(int argc, char * argv[])
301297 // End execution phase
302298
303299 // Teardown phase
300+ // deallocation is handled automatically by objects going out of scope
301+ running = false ;
304302
305303 printf (" PendulumMotor received %lu messages\n " , pendulum_motor->messages_received );
306304 printf (" PendulumController received %lu messages\n " , pendulum_controller->messages_received );
0 commit comments