仅使用发布表,一次分配内存,去除发布时多次分配内存的逻辑

This commit is contained in:
2025-12-30 10:48:59 +08:00
parent 3f378c0531
commit 79a5899717

View File

@@ -5,11 +5,10 @@
// #define MSG_OPT_DYNAMIC_SUB // 允许动态订阅 // #define MSG_OPT_DYNAMIC_SUB // 允许动态订阅
// #define MSG_OPT_DEBUG // 调试 // #define MSG_OPT_DEBUG // 调试
#define MSG_OPT_PUB_LIST // 使用静态发布表(多条消息单次分配内存)
/* 暂时不支持发布列表和动态订阅同时使用,后续需要再更新支持 */ /* 暂时不支持发布列表和动态订阅同时使用,后续需要再更新支持 */
#if defined(MSG_OPT_DYNAMIC_SUB) && defined(MSG_OPT_PUB_LIST) #if defined(MSG_OPT_DYNAMIC_SUB)
#error "These two functions are not currently supported to be used together." #error "These functions is not currently supported to be used together."
#endif #endif
#ifdef MSG_OPT_DEBUG #ifdef MSG_OPT_DEBUG
@@ -21,7 +20,6 @@
#define MSG_ASSERT {while(1);} #define MSG_ASSERT {while(1);}
#pragma pack(1) #pragma pack(1)
#ifdef MSG_OPT_PUB_LIST
/* 消息数据 */ /* 消息数据 */
typedef struct { typedef struct {
unsigned char module_id; // 发布的模块ID unsigned char module_id; // 发布的模块ID
@@ -34,18 +32,8 @@ typedef struct {
struct list_head list; // 消息链表 struct list_head list; // 消息链表
has_msg_buffer_t *msg_buff; has_msg_buffer_t *msg_buff;
} has_msg_node_t; } has_msg_node_t;
#else
/* 消息节点和数据 */
typedef struct {
unsigned char module_id; // 发布的模块ID
struct list_head list; // 消息链表
unsigned int length;
unsigned char buffer[];
} has_msg_node_t;
#endif
#pragma pack() #pragma pack()
#ifdef MSG_OPT_PUB_LIST
/* 静态发布列表 */ /* 静态发布列表 */
typedef struct { typedef struct {
unsigned char pub_module[MODULE_MAX - 1]; // 发布表 unsigned char pub_module[MODULE_MAX - 1]; // 发布表
@@ -55,7 +43,6 @@ typedef struct {
unsigned char pub_num; unsigned char pub_num;
} has_static_pub_list_t; } has_static_pub_list_t;
static has_static_pub_list_t g_pub_list[MODULE_MAX] = {0}; static has_static_pub_list_t g_pub_list[MODULE_MAX] = {0};
#endif
/* 静态订阅列表 */ /* 静态订阅列表 */
typedef struct { typedef struct {
@@ -94,9 +81,7 @@ int has_msg_init()
int j; int j;
/* 设置无效,标记是否初始化 */ /* 设置无效,标记是否初始化 */
memset(g_sub_list_index, MODULE_MAX, sizeof(g_sub_list_index)); memset(g_sub_list_index, MODULE_MAX, sizeof(g_sub_list_index));
#ifdef MSG_OPT_PUB_LIST
memset(g_pub_list, 0, sizeof(g_pub_list)); memset(g_pub_list, 0, sizeof(g_pub_list));
#endif
for (int i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++) { for (int i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++) {
/* 检查各模块ID是否配置正确 */ /* 检查各模块ID是否配置正确 */
if ((g_sub_list[i].module_id >= MODULE_MAX) || (g_sub_list[i].module_id == INVALID_ID)) { if ((g_sub_list[i].module_id >= MODULE_MAX) || (g_sub_list[i].module_id == INVALID_ID)) {
@@ -129,7 +114,6 @@ int has_msg_init()
return -1; return -1;
} }
g_sub_list_index[g_sub_list[i].module_id] = i; // 索引表赋值 g_sub_list_index[g_sub_list[i].module_id] = i; // 索引表赋值
#ifdef MSG_OPT_PUB_LIST
/* 通知发布者,需要发给此模块 */ /* 通知发布者,需要发给此模块 */
for (int k = 0; k < g_sub_list[i].sub_module_cnt; k++) { // 寻找发布者 for (int k = 0; k < g_sub_list[i].sub_module_cnt; k++) { // 寻找发布者
if (g_pub_list[g_sub_list[i].sub_module[k]].pub_num == 0) { if (g_pub_list[g_sub_list[i].sub_module[k]].pub_num == 0) {
@@ -140,7 +124,6 @@ int has_msg_init()
g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = g_sub_list[i].module_id; g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = g_sub_list[i].module_id;
g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++; g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++;
} }
#endif
msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量 msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量
INIT_LIST_HEAD(&g_sub_list[i].msg_list); // 初始化订阅链表 INIT_LIST_HEAD(&g_sub_list[i].msg_list); // 初始化订阅链表
} }
@@ -157,7 +140,6 @@ int has_msg_init()
// } // }
// msg_printf("\n"); // msg_printf("\n");
// } // }
#ifdef MSG_OPT_PUB_LIST
// msg_printf("\n"); // msg_printf("\n");
// for (int i = 1; i < MODULE_MAX; i++) { // for (int i = 1; i < MODULE_MAX; i++) {
// msg_printf("module:%d publish to:\n", i); // msg_printf("module:%d publish to:\n", i);
@@ -166,7 +148,6 @@ int has_msg_init()
// } // }
// msg_printf("\n"); // msg_printf("\n");
// } // }
#endif
#endif #endif
return 0; return 0;
} }
@@ -184,10 +165,8 @@ int has_msg_init_module(has_module_ID_e module_id)
for (i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++) for (i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++)
{ {
if (g_sub_list[i].module_id == module_id) { if (g_sub_list[i].module_id == module_id) {
// g_sub_list_index[module_id] = MODULE_MAX; // g_sub_list_index[module_id] = MODULE_MAX;
// #ifdef MSG_OPT_PUB_LIST // g_pub_list[module_id].pub_num = 0;
// g_pub_list[module_id].pub_num = 0;
// #endif
/* 已经被初始化了,配置错误 */ /* 已经被初始化了,配置错误 */
if (g_sub_list_index[module_id] != MODULE_MAX) { if (g_sub_list_index[module_id] != MODULE_MAX) {
msg_printf("[msg]warning: msg two same module id:%d\n", module_id); msg_printf("[msg]warning: msg two same module id:%d\n", module_id);
@@ -214,7 +193,6 @@ int has_msg_init_module(has_module_ID_e module_id)
} }
g_sub_list_index[module_id] = i; // 索引表赋值 g_sub_list_index[module_id] = i; // 索引表赋值
#ifdef MSG_OPT_PUB_LIST
/* 通知发布者,需要发给此模块 */ /* 通知发布者,需要发给此模块 */
for (int k = 0; k < g_sub_list[i].sub_module_cnt; k++) { // 寻找发布者 for (int k = 0; k < g_sub_list[i].sub_module_cnt; k++) { // 寻找发布者
if (g_pub_list[g_sub_list[i].sub_module[k]].pub_num == 0) { if (g_pub_list[g_sub_list[i].sub_module[k]].pub_num == 0) {
@@ -225,7 +203,6 @@ int has_msg_init_module(has_module_ID_e module_id)
g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = module_id; g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = module_id;
g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++; g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++;
} }
#endif
msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量 msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量
INIT_LIST_HEAD(&g_sub_list[i].msg_list); // 初始化订阅链表 INIT_LIST_HEAD(&g_sub_list[i].msg_list); // 初始化订阅链表
break; break;
@@ -246,9 +223,7 @@ int has_msg_os_init()
{ {
/* 设置无效,标记是否初始化 */ /* 设置无效,标记是否初始化 */
memset(g_sub_list_index, MODULE_MAX, sizeof(g_sub_list_index)); memset(g_sub_list_index, MODULE_MAX, sizeof(g_sub_list_index));
#ifdef MSG_OPT_PUB_LIST
memset(g_pub_list, 0, sizeof(g_pub_list)); memset(g_pub_list, 0, sizeof(g_pub_list));
#endif
// for(;;) // for(;;)
// has_msg_init_module(GUI); // has_msg_init_module(GUI);
// has_msg_init_module(SENSOR); // has_msg_init_module(SENSOR);
@@ -267,7 +242,6 @@ int has_msg_publish(has_module_ID_e module_id, void *buffer, unsigned int length
// if (length == 0) { // if (length == 0) {
// return -1; // return -1;
// } // }
#ifdef MSG_OPT_PUB_LIST
has_msg_buffer_t *msg_buffer; has_msg_buffer_t *msg_buffer;
unsigned char sub_index; unsigned char sub_index;
@@ -297,49 +271,11 @@ int has_msg_publish(has_module_ID_e module_id, void *buffer, unsigned int length
list_add_tail(&node[i].list, &g_sub_list[sub_index].msg_list); // 加入消息链表 list_add_tail(&node[i].list, &g_sub_list[sub_index].msg_list); // 加入消息链表
msg_mutex_unlock(&g_sub_list[sub_index].msg_mutex); msg_mutex_unlock(&g_sub_list[sub_index].msg_mutex);
} }
#else
int i;
msg_debug("publish: id:%d\n", module_id);
for (i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++) { // 遍历模块
#ifdef MSG_OPT_DYNAMIC_SUB
msg_mutex_lock(&g_sub_list[i].msg_mutex);
#endif
for (int j = 0; j < g_sub_list[i].sub_module_cnt; j++) { // 查找订阅表
if ((unsigned char)module_id == g_sub_list[i].sub_module[j]) { // 找到订阅信息
node = msg_malloc(sizeof(has_msg_node_t) + length);
msg_debug("node addr:0x%p\n", node);
if (node == NULL) {
msg_printf("malloc fail,pub id:%d\n", module_id);
#ifdef MSG_OPT_DYNAMIC_SUB
msg_mutex_unlock(&g_sub_list[i].msg_mutex);
#endif
return -1;
}
node->length = length;
node->module_id = module_id;
memcpy(node->buffer, buffer, length);
#ifndef MSG_OPT_DYNAMIC_SUB
msg_mutex_lock(&g_sub_list[i].msg_mutex);
#endif
list_add_tail(&node->list, &g_sub_list[i].msg_list); // 加入消息链表
#ifndef MSG_OPT_DYNAMIC_SUB
msg_mutex_unlock(&g_sub_list[i].msg_mutex);
#endif
break; // 不可重复订阅
}
}
#ifdef MSG_OPT_DYNAMIC_SUB
msg_mutex_unlock(&g_sub_list[i].msg_mutex);
#endif
}
#endif
return 0; return 0;
} }
/* TODO:更合理的方式是每个消息一个互斥量但是可能会导致每个消息malloc和free的时候频繁init和deinit */ /* TODO:更合理的方式是每个消息一个互斥量但是可能会导致每个消息malloc和free的时候频繁init和deinit */
#ifdef MSG_OPT_PUB_LIST
/* 检查计数判断该消息是否被所有订阅模块处理完,处理完就释放内存 */ /* 检查计数判断该消息是否被所有订阅模块处理完,处理完就释放内存 */
static inline void msg_check_and_free_message(has_msg_node_t *node) static inline void msg_check_and_free_message(has_msg_node_t *node)
{ {
@@ -359,7 +295,6 @@ static inline void msg_check_and_free_message(has_msg_node_t *node)
msg_free(temp); msg_free(temp);
} }
} }
#endif
int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb) int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb)
{ {
@@ -380,19 +315,11 @@ int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb)
return -1; return -1;
} }
#ifdef MSG_OPT_PUB_LIST
if (cb != NULL) { if (cb != NULL) {
cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length); cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length);
} }
msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id); msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id);
msg_check_and_free_message(node); msg_check_and_free_message(node);
#else
if (cb != NULL) {
cb(node->module_id, node->buffer, node->length);
}
msg_debug("handle:pub id:%d handle id:%d free addr:0x%p\n", node->module_id, module_id, node);
msg_free(node);
#endif
return 0; return 0;
@@ -411,11 +338,7 @@ int has_msg_handle_by_module(has_module_ID_e module_id, has_msg_handle_cb cb, ha
msg_mutex_lock(&sub_list->msg_mutex); msg_mutex_lock(&sub_list->msg_mutex);
if (!list_empty(&sub_list->msg_list)) { if (!list_empty(&sub_list->msg_list)) {
list_for_each_entry_safe(node, temp, &sub_list->msg_list, list) { list_for_each_entry_safe(node, temp, &sub_list->msg_list, list) {
#ifdef MSG_OPT_PUB_LIST
if (node->msg_buff->module_id == pub_module_id) { if (node->msg_buff->module_id == pub_module_id) {
#else
if (node->module_id == pub_module_id) {
#endif
list_del(&node->list); list_del(&node->list);
break; break;
} }
@@ -426,19 +349,11 @@ int has_msg_handle_by_module(has_module_ID_e module_id, has_msg_handle_cb cb, ha
return -1; return -1;
} }
#ifdef MSG_OPT_PUB_LIST
if (cb != NULL) { if (cb != NULL) {
cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length); cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length);
} }
msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id); msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id);
msg_check_and_free_message(node); msg_check_and_free_message(node);
#else
if (cb != NULL) {
cb(node->module_id, node->buffer, node->length);
}
msg_debug("handle:pub id:%d handle id:%d free addr:0x%p\n", node->module_id, module_id, node);
msg_free(node);
#endif
return 0; return 0;
@@ -463,19 +378,11 @@ int has_msg_handle_latest(has_module_ID_e module_id, has_msg_handle_cb cb)
return -1; return -1;
} }
#ifdef MSG_OPT_PUB_LIST
if (cb != NULL) { if (cb != NULL) {
cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length); cb(node->msg_buff->module_id, node->msg_buff->buffer, node->msg_buff->length);
} }
msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id); msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id);
msg_check_and_free_message(node); msg_check_and_free_message(node);
#else
if (cb != NULL) {
cb(node->module_id, node->buffer, node->length);
}
msg_debug("handle:pub id:%d handle id:%d free addr:0x%p\n", node->module_id, module_id, node);
msg_free(node);
#endif
return 0; return 0;
@@ -507,7 +414,6 @@ unsigned int has_msg_receive(has_module_ID_e module_id, unsigned char *pub_modul
return 0; return 0;
} }
#ifdef MSG_OPT_PUB_LIST
memcpy(buf_out, node->msg_buff->buffer, node->msg_buff->length); memcpy(buf_out, node->msg_buff->buffer, node->msg_buff->length);
if (pub_module_id != NULL) { if (pub_module_id != NULL) {
*pub_module_id = node->msg_buff->module_id; *pub_module_id = node->msg_buff->module_id;
@@ -515,16 +421,6 @@ unsigned int has_msg_receive(has_module_ID_e module_id, unsigned char *pub_modul
len = node->msg_buff->length; len = node->msg_buff->length;
msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id); msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id);
msg_check_and_free_message(node); msg_check_and_free_message(node);
#else
memcpy(buf_out, node->buffer, node->length);
if (pub_module_id != NULL) {
*pub_module_id = node->module_id;
}
len = node->length;
msg_debug("handle:pub id:%d handle id:%d free addr:0x%p\n", node->module_id, module_id, node);
msg_free(node);
#endif
return len; return len;
} }
@@ -552,7 +448,6 @@ unsigned int has_msg_receive_latest(has_module_ID_e module_id, unsigned char *pu
return 0; return 0;
} }
#ifdef MSG_OPT_PUB_LIST
memcpy(buf_out, node->msg_buff->buffer, node->msg_buff->length); memcpy(buf_out, node->msg_buff->buffer, node->msg_buff->length);
if (pub_module_id != NULL) { if (pub_module_id != NULL) {
*pub_module_id = node->msg_buff->module_id; *pub_module_id = node->msg_buff->module_id;
@@ -560,16 +455,6 @@ unsigned int has_msg_receive_latest(has_module_ID_e module_id, unsigned char *pu
len = node->msg_buff->length; len = node->msg_buff->length;
msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id); msg_debug("handle:pub id:%d handle id:%d\n", node->msg_buff->module_id, module_id);
msg_check_and_free_message(node); msg_check_and_free_message(node);
#else
memcpy(buf_out, node->buffer, node->length);
if (pub_module_id != NULL) {
*pub_module_id = node->module_id;
}
len = node->length;
msg_debug("handle:pub id:%d handle id:%d free addr:0x%p\n", node->module_id, module_id, node);
msg_free(node);
#endif
return len; return len;
} }
#endif #endif
@@ -629,12 +514,10 @@ int has_msg_delete_all_message(has_module_ID_e module_id)
{ {
has_msg_node_t *node, *temp; has_msg_node_t *node, *temp;
has_static_sub_list_t *sub_list; has_static_sub_list_t *sub_list;
#ifdef MSG_OPT_PUB_LIST
struct list_head free_list; struct list_head free_list;
has_msg_node_t *free_temp; has_msg_node_t *free_temp;
unsigned char id; unsigned char id;
INIT_LIST_HEAD(&free_list); INIT_LIST_HEAD(&free_list);
#endif
MSG_CHECK_ID_AND_INDEX(module_id, -1); MSG_CHECK_ID_AND_INDEX(module_id, -1);
sub_list = &g_sub_list[g_sub_list_index[module_id]]; sub_list = &g_sub_list[g_sub_list_index[module_id]];
@@ -643,17 +526,11 @@ int has_msg_delete_all_message(has_module_ID_e module_id)
if (!list_empty(&sub_list->msg_list)) { if (!list_empty(&sub_list->msg_list)) {
list_for_each_entry_safe(node, temp, &sub_list->msg_list, list) { list_for_each_entry_safe(node, temp, &sub_list->msg_list, list) {
list_del(&node->list); list_del(&node->list);
#ifdef MSG_OPT_PUB_LIST
list_add_tail(&node->list, &free_list); // 加入临时链表 list_add_tail(&node->list, &free_list); // 加入临时链表
#else
msg_debug("id:%d free addr:0x%p\n", module_id, node);
msg_free(node);
#endif
} }
} }
INIT_LIST_HEAD(&sub_list->msg_list); INIT_LIST_HEAD(&sub_list->msg_list);
msg_mutex_unlock(&sub_list->msg_mutex); msg_mutex_unlock(&sub_list->msg_mutex);
#ifdef MSG_OPT_PUB_LIST
/* 释放内存 */ /* 释放内存 */
list_for_each_entry_safe(node, temp, &free_list, list) { list_for_each_entry_safe(node, temp, &free_list, list) {
/* msg_check_and_free_message(node); */ /* msg_check_and_free_message(node); */
@@ -670,7 +547,6 @@ int has_msg_delete_all_message(has_module_ID_e module_id)
msg_free(free_temp); msg_free(free_temp);
} }
} }
#endif
return 0; return 0;
} }