Skip to content

Commit 2a30008

Browse files
authored
Rmw preallocate (#160)
* Add methods related to middleware preallocation. Signed-off-by: Michael Carroll <[email protected]> * Changes to support RMW preallocation Signed-off-by: Gonzalo de Pedro <[email protected]> Signed-off-by: Michael Carroll <[email protected]> * added fini for subscription allocation Signed-off-by: Michael Carroll <[email protected]> * Address reviewer feedback. Signed-off-by: Michael Carroll <[email protected]> * Documentation. Signed-off-by: Michael Carroll <[email protected]> * Apply suggestions from code review Signed-off-by: Michael Carroll <[email protected]> * Add allocation to `serialized_*` methods. Additionally updates documentation accordingly. Signed-off-by: Michael Carroll <[email protected]> * Apply suggestions from code review Signed-off-by: Michael Carroll <[email protected]> * Restore documentation for message_info. Signed-off-by: Michael Carroll <[email protected]>
1 parent ba0a717 commit 2a30008

File tree

2 files changed

+176
-15
lines changed

2 files changed

+176
-15
lines changed

rmw/include/rmw/rmw.h

Lines changed: 164 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ extern "C"
8989

9090
#include "rcutils/types.h"
9191

92+
#include "rosidl_generator_c/message_bounds_struct.h"
9293
#include "rosidl_generator_c/message_type_support_struct.h"
9394
#include "rosidl_generator_c/service_type_support_struct.h"
9495

@@ -214,6 +215,46 @@ RMW_WARN_UNUSED
214215
const rmw_guard_condition_t *
215216
rmw_node_get_graph_guard_condition(const rmw_node_t * node);
216217

218+
/// Initialize a publisher allocation to be used with later publications.
219+
/**
220+
* This creates an allocation object that can be used in conjunction with
221+
* the rmw_publish method to perform more carefully control memory allocations.
222+
*
223+
* This will allow the middleware to preallocate the correct amount of memory
224+
* for a given message type and message bounds.
225+
* As allocation is performed in this method, it will not be necessary to allocate
226+
* in the `rmw_publish` method.
227+
*
228+
* \param[in] type_support Type support of the message to be preallocated.
229+
* \param[in] message_bounds Bounds structure of the message to be preallocated.
230+
* \param[out] allocation Allocation structure to be passed to `rmw_publish`.
231+
* \return `RMW_RET_OK` if successful, or
232+
* \return `RMW_RET_INVALID_ARGUMENT` if an argument is null, or
233+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
234+
*/
235+
RMW_PUBLIC
236+
RMW_WARN_UNUSED
237+
rmw_ret_t
238+
rmw_init_publisher_allocation(
239+
const rosidl_message_type_support_t * type_support,
240+
const rosidl_message_bounds_t * message_bounds,
241+
rmw_publisher_allocation_t * allocation);
242+
243+
/// Destroy a publisher allocation object.
244+
/**
245+
* This deallocates any memory allocated by `rmw_init_publisher_allocation`.
246+
*
247+
* \param[in] allocation Allocation object to be destroyed.
248+
* \return `RMW_RET_OK` if successful, or
249+
* \return `RMW_RET_INVALID_ARGUMENT` if argument is null, or
250+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
251+
*/
252+
RMW_PUBLIC
253+
RMW_WARN_UNUSED
254+
rmw_ret_t
255+
rmw_fini_publisher_allocation(
256+
rmw_publisher_allocation_t * allocation);
257+
217258
RMW_PUBLIC
218259
RMW_WARN_UNUSED
219260
rmw_publisher_t *
@@ -228,10 +269,24 @@ RMW_WARN_UNUSED
228269
rmw_ret_t
229270
rmw_destroy_publisher(rmw_node_t * node, rmw_publisher_t * publisher);
230271

272+
/// Publish a given ros_message
273+
/**
274+
* Publish a given ROS message via a publisher.
275+
*
276+
* \param[in] publisher Publisher to be used to send message.
277+
* \param[in] ros_message Message to be sent.
278+
* \param[in] allocation Specify preallocated memory to use (may be NULL).
279+
* \return `RMW_RET_OK` if successful, or
280+
* \return `RMW_RET_INVALID_ARGUMENT` if publisher or ros_message is null, or
281+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
282+
*/
231283
RMW_PUBLIC
232284
RMW_WARN_UNUSED
233285
rmw_ret_t
234-
rmw_publish(const rmw_publisher_t * publisher, const void * ros_message);
286+
rmw_publish(
287+
const rmw_publisher_t * publisher,
288+
const void * ros_message,
289+
rmw_publisher_allocation_t * allocation);
235290

236291
/// Retrieve the number of matched subscriptions to a publisher.
237292
/**
@@ -285,16 +340,38 @@ rmw_publisher_get_actual_qos(
285340
* having to serialize the message first.
286341
* A ROS message can be serialized manually using the rmw_serialize() function.
287342
*
288-
* \param publisher the publisher object registered to send the message
289-
* \param serialized_message the serialized message holding the byte stream
343+
* \param[in] publisher The publisher object registered to send the message.
344+
* \param[in] serialized_message The serialized message holding the byte stream.
345+
* \param[in] allocation Specify preallocated memory to use (may be NULL).
290346
* \return `RMW_RET_OK` if successful, or
291347
* \return `RMW_RET_ERROR` if an unexpected error occurs.
292348
*/
293349
RMW_PUBLIC
294350
RMW_WARN_UNUSED
295351
rmw_ret_t
296352
rmw_publish_serialized_message(
297-
const rmw_publisher_t * publisher, const rmw_serialized_message_t * serialized_message);
353+
const rmw_publisher_t * publisher,
354+
const rmw_serialized_message_t * serialized_message,
355+
rmw_publisher_allocation_t * allocation);
356+
357+
/// Compute the size of a serialized message.
358+
/**
359+
* Given a message definition and bounds, compute the serialized size.
360+
*
361+
* \param[in] type_support The type support of the message to compute.
362+
* \param[in] bounds Artifical bounds to use on unbounded fields.
363+
* \param[out] size The computed size of the serialized message.
364+
* \return `RMW_RET_OK` if successful, or
365+
* \return `RMW_RET_INVALID_ARGUMENT` if either argument is null, or
366+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
367+
*/
368+
RMW_PUBLIC
369+
RMW_WARN_UNUSED
370+
rmw_ret_t
371+
rmw_get_serialized_message_size(
372+
const rosidl_message_type_support_t * type_support,
373+
const rosidl_message_bounds_t * message_bounds,
374+
size_t * size);
298375

299376
/// Serialize a ROS message into a rmw_serialized_message_t.
300377
/**
@@ -341,6 +418,46 @@ rmw_deserialize(
341418
const rosidl_message_type_support_t * type_support,
342419
void * ros_message);
343420

421+
/// Initialize a subscription allocation to be used with later `take`s.
422+
/**
423+
* This creates an allocation object that can be used in conjunction with
424+
* the rmw_take method to perform more carefully control memory allocations.
425+
*
426+
* This will allow the middleware to preallocate the correct amount of memory
427+
* for a given message type and message bounds.
428+
* As allocation is performed in this method, it will not be necessary to allocate
429+
* in the `rmw_take` method.
430+
*
431+
* \param[in] type_support Type support of the message to be preallocated.
432+
* \param[in] message_bounds Bounds structure of the message to be preallocated.
433+
* \param[out] allocation Allocation structure to be passed to `rmw_take`.
434+
* \return `RMW_RET_OK` if successful, or
435+
* \return `RMW_RET_INVALID_ARGUMENT` if an argument is null, or
436+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
437+
*/
438+
RMW_PUBLIC
439+
RMW_WARN_UNUSED
440+
rmw_ret_t
441+
rmw_init_subscription_allocation(
442+
const rosidl_message_type_support_t * type_support,
443+
const rosidl_message_bounds_t * message_bounds,
444+
rmw_subscription_allocation_t * allocation);
445+
446+
/// Destroy a publisher allocation object.
447+
/**
448+
* This deallocates memory allocated by `rmw_init_subscription_allocation`.
449+
*
450+
* \param[in] allocation Allocation object to be destroyed.
451+
* \return `RMW_RET_OK` if successful, or
452+
* \return `RMW_RET_INVALID_ARGUMENT` if argument is null, or
453+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
454+
*/
455+
RMW_PUBLIC
456+
RMW_WARN_UNUSED
457+
rmw_ret_t
458+
rmw_fini_subscription_allocation(
459+
rmw_subscription_allocation_t * allocation);
460+
344461
RMW_PUBLIC
345462
RMW_WARN_UNUSED
346463
rmw_subscription_t *
@@ -374,19 +491,47 @@ rmw_subscription_count_matched_publishers(
374491
const rmw_subscription_t * subscription,
375492
size_t * publisher_count);
376493

494+
/// Take an incoming message from a subscription.
495+
/**
496+
* Take an incoming ROS message from a given subscription.
497+
*
498+
* \param[in] subscription The subscription object to take from.
499+
* \param[out] ros_message The ROS message data on success.
500+
* \param[out] taken Boolean flag indicating if a message was taken or not.
501+
* \param[in] allocation Preallocated buffer to use (may be NULL).
502+
* \return `RMW_RET_OK` if successful, or
503+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
504+
*/
377505
RMW_PUBLIC
378506
RMW_WARN_UNUSED
379507
rmw_ret_t
380-
rmw_take(const rmw_subscription_t * subscription, void * ros_message, bool * taken);
508+
rmw_take(
509+
const rmw_subscription_t * subscription,
510+
void * ros_message,
511+
bool * taken,
512+
rmw_subscription_allocation_t * allocation);
381513

514+
/// Take an incoming message from a subscription with additional metadata.
515+
/**
516+
* Take an incoming ROS message from a given subscription.
517+
*
518+
* \param[in] subscription The subscription object to take from.
519+
* \param[out] ros_message The ROS message data on success.
520+
* \param[out] taken Boolean flag indicating if a message was taken or not.
521+
* \param[out] message_info Additional message metadata.
522+
* \param[in] allocation Preallocated buffer to use (may be NULL).
523+
* \return `RMW_RET_OK` if successful, or
524+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
525+
*/
382526
RMW_PUBLIC
383527
RMW_WARN_UNUSED
384528
rmw_ret_t
385529
rmw_take_with_info(
386530
const rmw_subscription_t * subscription,
387531
void * ros_message,
388532
bool * taken,
389-
rmw_message_info_t * message_info);
533+
rmw_message_info_t * message_info,
534+
rmw_subscription_allocation_t * allocation);
390535

391536
/// Take a message without deserializing it.
392537
/**
@@ -397,9 +542,10 @@ rmw_take_with_info(
397542
* If needed, this byte stream can then be deserialized in a ROS message with a call to
398543
* rmw_deserialize.
399544
*
400-
* \param subscription subscription object to take from
401-
* \param serialized_message the destination in which to store the serialized message
402-
* \param taken boolean flag indicating if a message was taken or not
545+
* \param[in] subscription Subscription object to take from.
546+
* \param[out] serialized_message The destination in which to store the serialized message.
547+
* \param[out] taken Boolean flag indicating if a message was taken or not.
548+
* \param[in] allocation Preallocated buffer to use (may be NULL).
403549
* \return `RMW_RET_OK` if successful, or
404550
* \return `RMW_RET_BAD_ALLOC` if memory allocation failed, or
405551
* \return `RMW_RET_ERROR` if an unexpected error occurs.
@@ -410,17 +556,19 @@ rmw_ret_t
410556
rmw_take_serialized_message(
411557
const rmw_subscription_t * subscription,
412558
rmw_serialized_message_t * serialized_message,
413-
bool * taken);
559+
bool * taken,
560+
rmw_subscription_allocation_t * allocation);
414561

415562
/// Take a message without deserializing it and with its additional message information.
416563
/**
417564
* The same as rmw_take_serialized_message(), except it also includes the
418565
* rmw_message_info_t.
419566
*
420-
* \param subscription subscription object to take from
421-
* \param serialized_message the destination in which to store the serialized message
422-
* \param taken boolean flag indicating if a message was taken or not
423-
* \param message_info a structure containing meta information about the taken message
567+
* \param[in] subscription Subscription object to take from.
568+
* \param[out] serialized_message The destination in which to store the serialized message.
569+
* \param[out] taken Boolean flag indicating if a message was taken or not.
570+
* \param[out] message_info A structure containing meta information about the taken message.
571+
* \param[in] allocation Preallocated buffer to use (may be NULL).
424572
* \return `RMW_RET_OK` if successful, or
425573
* \return `RMW_RET_BAD_ALLOC` if memory allocation failed, or
426574
* \return `RMW_RET_ERROR` if an unexpected error occurs.
@@ -432,7 +580,8 @@ rmw_take_serialized_message_with_info(
432580
const rmw_subscription_t * subscription,
433581
rmw_serialized_message_t * serialized_message,
434582
bool * taken,
435-
rmw_message_info_t * message_info);
583+
rmw_message_info_t * message_info,
584+
rmw_subscription_allocation_t * allocation);
436585

437586
RMW_PUBLIC
438587
RMW_WARN_UNUSED

rmw/include/rmw/types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ typedef struct RMW_PUBLIC_TYPE rmw_guard_condition_t
8080
rmw_context_t * context;
8181
} rmw_guard_condition_t;
8282

83+
typedef struct RMW_PUBLIC_TYPE rmw_publisher_allocation_t
84+
{
85+
const char * implementation_identifier;
86+
void * data;
87+
} rmw_publisher_allocation_t;
88+
89+
typedef struct RMW_PUBLIC_TYPE rmw_subscription_allocation_t
90+
{
91+
const char * implementation_identifier;
92+
void * data;
93+
} rmw_subscription_allocation_t;
94+
8395
/// Array of subscriber handles.
8496
/**
8597
* An array of void * pointers representing type-erased middleware-specific subscriptions.

0 commit comments

Comments
 (0)