diff --git a/rmw_microxrcedds_c/CMakeLists.txt b/rmw_microxrcedds_c/CMakeLists.txt index 3a90dcfb..0ea5212a 100644 --- a/rmw_microxrcedds_c/CMakeLists.txt +++ b/rmw_microxrcedds_c/CMakeLists.txt @@ -49,6 +49,7 @@ set(RMW_UXRCE_MAX_PUBLISHERS "4" CACHE STRING "This value sets the maximum numbe set(RMW_UXRCE_MAX_SUBSCRIPTIONS "4" CACHE STRING "This value sets the maximum number of subscriptions for an application.") set(RMW_UXRCE_MAX_SERVICES "4" CACHE STRING "This value sets the maximum number of services for an application.") set(RMW_UXRCE_MAX_CLIENTS "4" CACHE STRING "This value sets the maximum number of clients for an application.") +set(RMW_UXRCE_MAX_TOPICS "-1" CACHE STRING "This value sets the maximum number of topics for an application. If set to -1 RMW_UXRCE_MAX_TOPICS = RMW_UXRCE_MAX_PUBLISHERS + RMW_UXRCE_MAX_SUBSCRIPTIONS + RMW_UXRCE_MAX_NODES.") set(RMW_UXRCE_NODE_NAME_MAX_LENGTH "128" CACHE STRING "This value sets the maximum number of characters for a node name.") set(RMW_UXRCE_TOPIC_NAME_MAX_LENGTH "100" CACHE STRING "This value sets the maximum number of characters for a topic name.") set(RMW_UXRCE_TYPE_NAME_MAX_LENGTH "128" CACHE STRING "This value sets the maximum number of characters for a type name.") diff --git a/rmw_microxrcedds_c/src/config.h.in b/rmw_microxrcedds_c/src/config.h.in index 4c614c7e..70f0e68c 100644 --- a/rmw_microxrcedds_c/src/config.h.in +++ b/rmw_microxrcedds_c/src/config.h.in @@ -31,6 +31,11 @@ #define RMW_UXRCE_MAX_SUBSCRIPTIONS @RMW_UXRCE_MAX_SUBSCRIPTIONS@ #define RMW_UXRCE_MAX_SERVICES @RMW_UXRCE_MAX_SERVICES@ #define RMW_UXRCE_MAX_CLIENTS @RMW_UXRCE_MAX_CLIENTS@ +#define RMW_UXRCE_MAX_TOPICS @RMW_UXRCE_MAX_TOPICS@ + +#if RMW_UXRCE_MAX_TOPICS == -1 +#define RMW_UXRCE_MAX_TOPICS RMW_UXRCE_MAX_PUBLISHERS + RMW_UXRCE_MAX_SUBSCRIPTIONS +#endif #define RMW_UXRCE_NODE_NAME_MAX_LENGTH @RMW_UXRCE_NODE_NAME_MAX_LENGTH@ #define RMW_UXRCE_TOPIC_NAME_MAX_LENGTH @RMW_UXRCE_TOPIC_NAME_MAX_LENGTH@ diff --git a/rmw_microxrcedds_c/src/rmw_init.c b/rmw_microxrcedds_c/src/rmw_init.c index 39d968fd..63d5e6ab 100644 --- a/rmw_microxrcedds_c/src/rmw_init.c +++ b/rmw_microxrcedds_c/src/rmw_init.c @@ -173,6 +173,7 @@ rmw_init(const rmw_init_options_t * options, rmw_context_t * context) rmw_uxrce_init_publisher_memory(&publisher_memory, custom_publishers, RMW_UXRCE_MAX_PUBLISHERS); rmw_uxrce_init_service_memory(&service_memory, custom_services, RMW_UXRCE_MAX_SERVICES); rmw_uxrce_init_client_memory(&client_memory, custom_clients, RMW_UXRCE_MAX_CLIENTS); + rmw_uxrce_init_topics_memory(&topics_memory, custom_topics, RMW_UXRCE_MAX_TOPICS); // Micro-XRCE-DDS Client initialization diff --git a/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.c b/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.c index 8a190fb9..bc65d933 100644 --- a/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.c +++ b/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.c @@ -29,39 +29,25 @@ create_topic( const message_type_support_callbacks_t * message_type_support_callbacks, const rmw_qos_profile_t * qos_policies) { - // TODO (pablogs9): Refactor topic memory and reutilization - rmw_uxrce_topic_t * custom_topic_ptr = custom_node->custom_topic_sp; - while (custom_topic_ptr != NULL) { - custom_topic_ptr = custom_topic_ptr->next_custom_topic; + struct rmw_uxrce_mempool_item_t * memory_node = get_memory(&topics_memory); + if (!memory_node) { + RMW_SET_ERROR_MSG("Not available memory node"); + goto fail; } - // Generate new memory - custom_topic_ptr = (rmw_uxrce_topic_t *)rmw_allocate(sizeof(rmw_uxrce_topic_t)); - if (custom_topic_ptr == NULL) { - RMW_SET_ERROR_MSG("failed to allocate topic interna mem"); - goto create_topic_end; - } + rmw_uxrce_topic_t * custom_topic = (rmw_uxrce_topic_t *)memory_node->data; // Init - custom_topic_ptr->sync_with_agent = false; - custom_topic_ptr->usage_account = 1; - custom_topic_ptr->owner_node = custom_node; - - // Add to top of the node stack - custom_topic_ptr->next_custom_topic = custom_node->custom_topic_sp; - if (custom_node->custom_topic_sp != NULL) { - custom_node->custom_topic_sp->prev_custom_topic = custom_topic_ptr; - } - custom_node->custom_topic_sp = custom_topic_ptr; - + custom_topic->sync_with_agent = false; + custom_topic->usage_account = 1; + custom_topic->owner_node = custom_node; // Asociate to typesupport - custom_topic_ptr->message_type_support_callbacks = message_type_support_callbacks; - + custom_topic->message_type_support_callbacks = message_type_support_callbacks; // Generate topic id - custom_topic_ptr->topic_id = uxr_object_id(custom_node->context->id_topic++, UXR_TOPIC_ID); + custom_topic->topic_id = uxr_object_id(custom_node->context->id_topic++, UXR_TOPIC_ID); #ifdef MICRO_XRCEDDS_USE_XML char xml_buffer[RMW_UXRCE_XML_BUFFER_LENGTH]; @@ -76,99 +62,40 @@ create_topic( qos_policies, xml_buffer, sizeof(xml_buffer))) { RMW_SET_ERROR_MSG("failed to generate xml request for subscriber creation"); - (void)destroy_topic(custom_topic_ptr); - custom_topic_ptr = NULL; - goto create_topic_end; + rmw_uxrce_fini_topic_memory(custom_topic); + custom_topic = NULL; + goto fail; } topic_req = uxr_buffer_create_topic_xml(&custom_node->context->session, - custom_node->context->reliable_output, custom_topic_ptr->topic_id, + custom_node->context->reliable_output, custom_topic->topic_id, custom_node->participant_id, xml_buffer, UXR_REPLACE); #elif defined(MICRO_XRCEDDS_USE_REFS) (void)qos_policies; if (!build_topic_profile(topic_name, profile_name, sizeof(profile_name))) { RMW_SET_ERROR_MSG("failed to generate xml request for node creation"); - (void)destroy_topic(custom_topic_ptr); - custom_topic_ptr = NULL; - goto create_topic_end; + rmw_uxrce_fini_topic_memory(custom_topic); + custom_topic = NULL; + goto fail; } topic_req = uxr_buffer_create_topic_ref(&custom_node->context->session, - custom_node->context->reliable_output, custom_topic_ptr->topic_id, + custom_node->context->reliable_output, custom_topic->topic_id, custom_node->participant_id, profile_name, UXR_REPLACE); #endif // Send the request and wait for response uint8_t status; - custom_topic_ptr->sync_with_agent = + custom_topic->sync_with_agent = uxr_run_session_until_all_status(&custom_node->context->session, 1000, &topic_req, &status, 1); - if (!custom_topic_ptr->sync_with_agent) { + if (!custom_topic->sync_with_agent) { RMW_SET_ERROR_MSG("Issues creating micro XRCE-DDS entities"); - (void)destroy_topic(custom_topic_ptr); - custom_topic_ptr = NULL; - goto create_topic_end; - } - - -create_topic_end: - - return custom_topic_ptr; -} - -bool -destroy_topic(rmw_uxrce_topic_t * custom_topic) -{ - bool ok = false; - - if (custom_topic != NULL) { - custom_topic->usage_account--; - if (custom_topic->usage_account <= 0) { - // Remove from the stack - if (custom_topic->next_custom_topic != NULL) { - custom_topic->next_custom_topic->prev_custom_topic = custom_topic->prev_custom_topic; - } - if (custom_topic->prev_custom_topic != NULL) { - custom_topic->prev_custom_topic->next_custom_topic = custom_topic->next_custom_topic; - } else { - custom_topic->owner_node->custom_topic_sp = NULL; - } - - if (custom_topic->sync_with_agent) { - uint16_t request = uxr_buffer_delete_entity(&custom_topic->owner_node->context->session, - custom_topic->owner_node->context->reliable_output, - custom_topic->topic_id); - uint8_t status; - if (!uxr_run_session_until_all_status(&custom_topic->owner_node->context->session, 1000, - &request, &status, 1)) - { - RMW_SET_ERROR_MSG("unable to remove publisher from the server"); - } else { - ok = true; - } - } else { - ok = true; - } - - rmw_free(custom_topic); - } else { - ok = true; - } - } - - return ok; -} - - -size_t -topic_count(struct rmw_uxrce_node_t * custom_node) -{ - size_t count = 0; - rmw_uxrce_topic_t * custom_topic_ptr = custom_node->custom_topic_sp; - while (custom_topic_ptr != NULL) { - count++; - custom_topic_ptr = custom_topic_ptr->next_custom_topic; + rmw_uxrce_fini_topic_memory(custom_topic); + custom_topic = NULL; + goto fail; } - return count; -} +fail: + return custom_topic; +} \ No newline at end of file diff --git a/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.h b/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.h index 2d8cbb75..47a946b8 100644 --- a/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.h +++ b/rmw_microxrcedds_c/src/rmw_microxrcedds_topic.h @@ -32,13 +32,6 @@ create_topic( const message_type_support_callbacks_t * message_type_support_callbacks, const rmw_qos_profile_t * qos_policies); - -bool -destroy_topic(rmw_uxrce_topic_t * custom_topic); - -size_t -topic_count(struct rmw_uxrce_node_t * custom_node); - #if defined(__cplusplus) } #endif diff --git a/rmw_microxrcedds_c/src/types.c b/rmw_microxrcedds_c/src/types.c index 759396df..274cc2a8 100644 --- a/rmw_microxrcedds_c/src/types.c +++ b/rmw_microxrcedds_c/src/types.c @@ -54,6 +54,10 @@ struct rmw_uxrce_mempool_t client_memory; rmw_uxrce_client_t custom_clients[RMW_UXRCE_MAX_CLIENTS]; static bool client_memory_init = false; +struct rmw_uxrce_mempool_t topics_memory; +rmw_uxrce_client_t custom_topics[RMW_UXRCE_MAX_TOPICS]; +static bool topic_memory_init = false; + // Memory init functions void rmw_uxrce_init_service_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_service_t * services, size_t size) @@ -146,6 +150,22 @@ void rmw_uxrce_init_sessions_memory(struct rmw_uxrce_mempool_t * memory, rmw_con } } +void rmw_uxrce_init_topics_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_topic_t * topics, size_t size) +{ + if (size > 0 && !topic_memory_init) { + topic_memory_init = true; + link_prev(NULL, &topics[0].mem, NULL); + size > 1 ? link_next(&topics[0].mem, &topics[1].mem, &topics[0]) : link_next(&topics[0].mem, NULL, + &topics[0]); + for (unsigned int i = 1; i <= size - 1; i++) { + link_prev(&topics[i - 1].mem, &topics[i].mem, &topics[i]); + } + link_next(&topics[size - 1].mem, NULL, &topics[size - 1]); + set_mem_pool(memory, &topics[0].mem); + } +} + + // Memory management functions void rmw_uxrce_fini_session_memory(rmw_context_impl_t * session) @@ -196,7 +216,7 @@ void rmw_uxrce_fini_publisher_memory(rmw_publisher_t * publisher) rmw_uxrce_publisher_t * custom_publisher = (rmw_uxrce_publisher_t *)publisher->data; if (custom_publisher->topic != NULL) { - destroy_topic(custom_publisher->topic); + rmw_uxrce_fini_topic_memory(custom_publisher->topic); } put_memory(&publisher_memory, &custom_publisher->mem); @@ -224,7 +244,7 @@ void rmw_uxrce_fini_subscription_memory(rmw_subscription_t * subscriber) rmw_uxrce_subscription_t * custom_subscription = (rmw_uxrce_subscription_t *)subscriber->data; if (custom_subscription->topic != NULL) { - destroy_topic(custom_subscription->topic); + rmw_uxrce_fini_topic_memory(custom_subscription->topic); } put_memory(&subscription_memory, &custom_subscription->mem); @@ -280,3 +300,9 @@ void rmw_uxrce_fini_client_memory(rmw_client_t * client) } rmw_free(client); } + +void rmw_uxrce_fini_topic_memory(rmw_uxrce_topic_t * topic) +{ + put_memory(&topics_memory, &topic->mem); + memset(topic, 0, sizeof(rmw_uxrce_topic_t)); +} diff --git a/rmw_microxrcedds_c/src/types.h b/rmw_microxrcedds_c/src/types.h index ce831469..d6a5efdc 100644 --- a/rmw_microxrcedds_c/src/types.h +++ b/rmw_microxrcedds_c/src/types.h @@ -93,8 +93,7 @@ struct rmw_init_options_impl_t typedef struct rmw_uxrce_topic_t { - struct rmw_uxrce_topic_t * next_custom_topic; - struct rmw_uxrce_topic_t * prev_custom_topic; + struct rmw_uxrce_mempool_item_t mem; uxrObjectId topic_id; const message_type_support_callbacks_t * message_type_support_callbacks; @@ -202,7 +201,6 @@ typedef struct rmw_uxrce_node_t struct rmw_context_impl_t * context; uxrObjectId participant_id; - rmw_uxrce_topic_t * custom_topic_sp; } rmw_uxrce_node_t; // Static memory pools @@ -225,6 +223,9 @@ extern rmw_uxrce_service_t custom_services[RMW_UXRCE_MAX_SERVICES]; extern struct rmw_uxrce_mempool_t client_memory; extern rmw_uxrce_client_t custom_clients[RMW_UXRCE_MAX_CLIENTS]; +extern struct rmw_uxrce_mempool_t topics_memory; +extern rmw_uxrce_client_t custom_topics[RMW_UXRCE_MAX_TOPICS]; + // Memory init functions void rmw_uxrce_init_sessions_memory(struct rmw_uxrce_mempool_t * memory, rmw_context_impl_t * sessions, size_t size); @@ -233,6 +234,7 @@ void rmw_uxrce_init_service_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrc void rmw_uxrce_init_client_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_client_t * clients, size_t size); void rmw_uxrce_init_publisher_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_publisher_t * publishers, size_t size); void rmw_uxrce_init_subscriber_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_subscription_t * subscribers, size_t size); +void rmw_uxrce_init_topics_memory(struct rmw_uxrce_mempool_t * memory, rmw_uxrce_topic_t * topics, size_t size); // Memory management functions @@ -242,5 +244,6 @@ void rmw_uxrce_fini_publisher_memory(rmw_publisher_t * publisher); void rmw_uxrce_fini_subscription_memory(rmw_subscription_t * subscriber); void rmw_uxrce_fini_client_memory(rmw_client_t * client); void rmw_uxrce_fini_service_memory(rmw_service_t * service); +void rmw_uxrce_fini_topic_memory(rmw_uxrce_topic_t * topic); #endif // RMW_MICROXRCEDDS_C__SRC__TYPES_H