ros2 / rosidl

Packages which provide the ROS IDL (.msg) definition and code generation.
Apache License 2.0
75 stars 125 forks source link

Investigate using rcutils allocators for the C generators #306

Open clalancette opened 5 years ago

clalancette commented 5 years ago

Based on a comment at https://github.com/ros2/rosidl/pull/300#issuecomment-432038951, we should see if we can/should use the rcutils allocators when generating the C code for messages/services. Then we could potentially create a custom allocator to test that messages are being properly freed on error paths.

allenh1 commented 5 years ago

@clalancette if it's alright with you, I'd be more than happy to look into this.

clalancette commented 5 years ago

@allenh1 We should probably coordinate with @wjwwood a bit on this, as he has "adding allocators" as part of the larger memory management list here: https://github.com/ros2/ros2/issues/590 . @wjwwood Do you have a plan to start working on that, or should we let @allenh1 loose on it?

wjwwood commented 5 years ago

I’m hesitant to turn away help but I have already started working on this in part. Specifically I’ve been adding allocator calls to the typesupport functions responsible for converting ros types to dds types. Which would in turn pass that allocator to the rosidl functions described here. Let me see if there’s a reasonable place to do separation of labor in this and get back to you.

allenh1 commented 5 years ago

@wjwwood of course! Thank you very much. Keep me posted!

y-okumura-isp commented 4 years ago

I'm interested in ROS2 realtype behavior, and checking malloc call(see Memory management in Introduction to Real-time Systems). I found some malloc calls such as rosidl_generator_c__String__init in rosidl/rosidl_generator_c/src/string_functions.c.

This is called at RCLCPP_INFO log macro, so called in run-time(ex. demo_nodes_cpp/src/topics/talker.cpp). And this is also called at convert_dds_to_ros of rosidl_typesupport_{DDS}, so I wonder this may affect subscription.

@wjwwood How is the situation on this issue? If the problem is unsolved, I'm thinking of writing a small patch. (As rcl package uses static rcl_allocator_t, I plan to convey rcl allocator to this layer and replace malloc() with allocate() of rcl allocator.)

wjwwood commented 4 years ago

If the problem is unsolved, I'm thinking of writing a small patch. (As rcl package uses static rcl_allocator_t, I plan to convey rcl allocator to this layer and replace malloc() with allocate() of rcl allocator.)

It is still unsolved, and I think changing the functions that use malloc internally so that they take a rcutils_allocator_t (I think using rcl_allocator_t might cause a circular reference as rcl uses some of the message types), is the right way to go.

wjwwood commented 4 years ago

I'll also add that we haven't done this yet because right now the C messages are mostly only used by Python, and the C++ ones have the allocator template argument to control their behavior (though that has issues too). The fact that logging creates a C message instance that uses malloc (for the strings I guess) is a relatively new change, and many of our users that are doing real-time replace the logging implementation anyways (so that it does not publish and therefore does not need to make a new message instance).

y-okumura-isp commented 4 years ago

@wjwwood Thank you for reply.

rcutils_allocator_t (snip) is the right way to go.

I see.

many of our users that are doing real-time replace the logging implementation anyways

Yeah, logging seems not a big problem.

How do you think the priority of below problems?

As break-points on these functions doesn't stop the program, I cannot judge the seriousness of these right now.

wjwwood commented 4 years ago

How do you think the priority of below problems?

Both of those are in the C type support (as opposed to the C++ type support). The only thing using the C type support right now is the Python client library (rclpy) and some tests in rcl, so I don't think they are hitting anyone at the moment (not urgent). But they should be addressed at some point. Basically anywhere we use malloc or new we should allow the user to override that somehow.

For the C++ equivalents, we are just using new and delete instead of malloc. But that can be controlled with the allocator template argument.

y-okumura-isp commented 4 years ago

I understand, thank you.

jacobperron commented 2 years ago

I think all calls to malloc and free have been replaced with the default allocator provided by rcutils in https://github.com/ros2/rosidl/pull/584

However, I think we should make further changes to accept a non-default allocator. I am planning to look into this.

pablogs9 commented 2 years ago

@jacobperron as commented by @y-okumura-isp, in micro-ROS we added a setter for the default allocator in our rcutils fork: https://github.com/micro-ROS/rcutils/blob/85efa4ad786fb6920ae92156ab439dec0315299b/src/allocator.c#L87

This allows a basic operation with custom allocators such as the FreeRTOS's heap managers.

jacobperron commented 2 years ago

I guess being able modify the default allocator is a valid solution, but it doesn't follow the pattern we use in many places in rcl where we pass in an allocator per function. Although passing in an allocator every time is more verbose, it is more flexible since we have the option to use different allocators in the same application. We can still have an API for creating messages with the default allocator.