UBS Atomic 对外接口文档 ​

本文档根据 include 目录下的公开头文件整理,面向调用方说明 UBS Atomic 共享内存原子能力的 C ABI 接口。当前对外能力包括:

  • 分布式共享内存通信队列:include/ub_dist_comm_queue.h
  • 分布式读写锁:include/ub_dist_lock.h
  • 分布式事务资源:include/ub_dist_tx_res.h
  • 通用日志接口:三个头文件均暴露同一组 ub_atomic_* 日志接口

接口默认支持 C/C++ 调用;C++ 场景下头文件使用 extern "C" 保持 C ABI。

1. 通用日志接口 ​

1.1 日志级别 ​

名称值说明
LOG_LEVEL_DEBUG0调试日志
LOG_LEVEL_INFO1普通信息日志
LOG_LEVEL_WARN2告警日志
LOG_LEVEL_ERROR3错误日志
LOG_LEVEL_CRITICAL4严重错误日志

1.2 ub_atomic_log_func ​

项目内容
名称ub_atomic_log_func
接口描述用户自定义日志函数类型,库内部产生日志时调用。
接口类型回调函数类型
函数原型typedef int (*ub_atomic_log_func)(int level, const char *file, const char *func, uint32_t line, const char *message);
返回参数int,由调用方自定义;当前库不依赖该返回值表达业务结果。

输入参数列表与参数有效性规格

参数名参数类型参数类型说明参数有效性规格
levelint日志级别建议为 LOG_LEVEL_DEBUG 到 LOG_LEVEL_CRITICAL
fileconst char *源文件名由库传入,回调内不应修改
funcconst char *函数名由库传入,回调内不应修改
lineuint32_t行号由库传入
messageconst char *格式化后的日志内容由库传入,回调内不应修改或长期持有裸指针

约束与注意事项

  • 回调函数应避免阻塞过久,否则可能影响调用接口的执行路径。
  • 回调中如需保存日志内容,应自行拷贝字符串。

1.3 ub_atomic_register_log_func ​

项目内容
名称ub_atomic_register_log_func
接口描述注册用户自定义日志函数。
接口类型函数
函数原型void ub_atomic_register_log_func(ub_atomic_log_func func);
返回参数无
参数名参数类型参数类型说明参数有效性规格
funcub_atomic_log_func日志回调函数指针可以传入有效函数指针;传入空指针表示取消或不使用用户日志函数,具体行为取决于内部日志模块

1.4 ub_atomic_set_log_level ​

项目内容
名称ub_atomic_set_log_level
接口描述设置日志输出阈值,低于阈值的日志不会输出。
接口类型函数
函数原型int ub_atomic_set_log_level(int level);
返回参数成功返回 0;非法日志级别返回 -1。
参数名参数类型参数类型说明参数有效性规格
levelint日志级别阈值必须在 LOG_LEVEL_DEBUG 到 LOG_LEVEL_CRITICAL 范围内

使用样例

c
#include "ub_dist_tx_res.h"
#include <stdio.h>

static int app_logger(int level, const char *file, const char *func, uint32_t line, const char *message)
{
    printf("[%d] %s:%u %s: %s\n", level, file, line, func, message);
    return 0;
}

void setup_log(void)
{
    ub_atomic_register_log_func(app_logger);
    (void)ub_atomic_set_log_level(LOG_LEVEL_INFO);
}

2. 分布式共享内存通信队列 ​

2.1 模块说明 ​

通信队列提供基于共享内存的多节点消息通道。每个节点在自己的 Ring 区域中创建本地收包 Ring,其他节点通过共享内存写入目标节点对应优先级的 Ring。主要收包路径为后台分发线程轮询本节点 Ring 并派发回调。

全局约束

  • 当前最大节点数为 16。
  • 当前最大优先级级别个数为 8,即 priority 取值范围为 0~7,数值越小级别越高。
  • priority == 0 为内部分布式锁 Ring 和系统消息保留,业务 Ring 配置不得使用 0。
  • 系统保留消息类型包括 0xFF、0xFE、0xFD,业务侧不应直接发送或注册这些消息类型。
  • ring_capacity 必须是 2 的幂。
  • UB_COMM_SEND_CONGESTED 的值为 1,表示消息已经入队但目标 Ring 达到拥塞阈值,不是失败。

2.2 公开数据结构 ​

ub_shm_area_t ​

字段类型说明参数有效性规格
sizesize_t共享内存区域大小,单位字节初始化公告牌区域时必须足够容纳内部公告牌;Ring 区域必须足够放置本节点所有 Ring
ptrvoid *共享内存首地址必须指向调用方已分配并映射好的共享内存

ub_ring_region_info_t ​

字段类型说明参数有效性规格
regionub_shm_area_t某个节点的 Ring 共享内存区域region.ptr 非空,region.size 满足该节点 Ring 空间需求
node_iduint8_t节点 ID必须在集群内唯一

ub_ring_region_map_t ​

字段类型说明参数有效性规格
entriesub_ring_region_info_t *所有节点 Ring 区域数组非空;各节点看到的数组内容和顺序应保持一致
countuint8_t数组元素个数非 0,且不超过 16;应等于 ub_comm_conf_t.max_nodes

ub_ring_desc_t ​

字段类型说明参数有效性规格
ring_capacityuint32_tRing 容量,按消息条目计必须是 2 的幂
max_msg_sizeuint32_t单条消息最大大小,单位字节必须能容纳消息头和业务消息体
priorityuint8_tRing 优先级业务 Ring 必须为 1~7,0 保留

ub_comm_conf_t ​

字段类型说明参数有效性规格
cpu_idint32_t分发线程绑核 CPU ID小于 0 表示不绑核;非负值应为有效 CPU ID
max_nodesuint8_t集群最大节点数1~16
current_node_iduint8_t当前节点 ID必须存在于 ring_regions.entries 中
num_ringsuint8_t当前节点创建的业务 Ring 数量1~7,且不包含内部保留 Ring
ring_descsub_ring_desc_t *Ring 配置数组非空,长度至少为 num_rings

message_header_t 与 message_t ​

字段类型说明参数有效性规格
src_thread_iduint64_t发送线程或逻辑线程 ID调用方自定义
body_lengthuint32_t消息体长度应与 message_t.body 指向的数据长度一致;消息头加消息体不得超过目标 Ring 的 max_msg_size
dest_node_iduint8_t目标节点 ID必须存在于节点映射中,且目标节点已初始化
src_node_iduint8_t源节点 ID必须等于当前通信实例的 current_node_id
msg_typeuint8_t业务消息类型不应使用系统保留值 0xFF、0xFE、0xFD
priorityuint8_t目标 Ring 优先级业务发送应使用已配置的 1~7
bodychar *消息体地址当 body_length > 0 时必须指向有效内存

ub_func_type_t 与 ub_callback_t ​

名称类型说明
ub_callback_tvoid (*)(const message_t *msg, void *ctx)消息处理回调类型
UB_FUNC_SYNC枚举值 0同步回调
UB_FUNC_ASYNC枚举值 1异步回调,投递到内部线程池执行

ub_comm_queue_status_t ​

字段类型说明
useduint64_t估算占用条目数
totaluint64_tRing 总容量
freeuint64_t估算空闲条目数
stateub_comm_queue_state_t队列状态
congestion_thresholduint64_t当前拥塞阈值对应的条目数
max_depthuint64_tRing 初始化以来观测到的最大深度

若编译时定义 UB_COMM_QUEUE_ENABLE_DEBUG_STATS,结构体还包含 full_fail_count、cas_fail_count、congestion_enter_ts_us、congestion_exit_ts_us。

state 名称说明
UB_COMM_QUEUE_IDLEused == 0
UB_COMM_QUEUE_NORMAL0 < used < congestion_threshold
UB_COMM_QUEUE_CONGESTEDused >= congestion_threshold && used < total
UB_COMM_QUEUE_FULLused >= total

ub_comm_queue_heartbeat_config_t ​

字段类型说明参数有效性规格
heartbeat_interval_msuint32_t本节点消费者心跳序号刷新周期,单位ms;会发布给其他节点用于超时窗口计算必须大于 0
check_interval_msuint32_t本节点生产者心跳监控线程轮询周期,单位ms必须大于 0
timeout_msuint32_t本节点观察 peer 的最小超时阈值,单位ms必须大于 0,且不小于 2 * check_interval_ms

2.3 ub_comm_queue_init ​

项目内容
名称ub_comm_queue_init
接口描述初始化共享内存通信实例,创建本地 Ring,发布节点状态,并启动后台分发线程。
接口类型函数
函数原型int ub_comm_queue_init(ub_shm_comm_t *handle, ub_shm_area_t *init_region, ub_ring_region_map_t *ring_regions, ub_comm_conf_t *conf);
返回参数成功返回 0;失败返回负数错误码,如 -EINVAL、-ENOMEM、-EFAULT 或内部初始化错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *输出通信实例句柄非空;成功后写入不透明句柄
init_regionub_shm_area_t *全局初始化公告牌共享内存非空;ptr 指向共享内存,size 足够容纳公告牌
ring_regionsub_ring_region_map_t *所有节点 Ring 区域映射非空;entries 非空;count 为 1~16
confub_comm_conf_t *当前节点通信配置非空;字段满足 2.2 中规格

约束与注意事项

  • 调用方负责分配和管理共享内存生命周期。
  • 所有节点应使用一致的 ring_regions 节点集合。
  • 第一个初始化成功的通信实例会被内部标记为分布式锁使用实例。
  • 初始化成功后必须调用 ub_comm_queue_deinit 释放实例。

2.4 ub_comm_queue_deinit ​

项目内容
名称ub_comm_queue_deinit
接口描述反初始化通信实例,停止后台线程并释放实例对象。
接口类型函数
函数原型int ub_comm_queue_deinit(ub_shm_comm_t *handle);
返回参数成功返回 0;handle == NULL 或 *handle == NULL 返回 -EINVAL。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 为初始化成功返回的有效句柄

约束与注意事项

  • 成功后接口会将 *handle 置为 NULL。
  • 调用该接口后,不得继续使用原句柄调用发送、查询或注册接口。

2.5 ub_comm_queue_send ​

项目内容
名称ub_comm_queue_send
接口描述向目标节点指定优先级 Ring 发送业务消息。
接口类型函数
函数原型int ub_comm_queue_send(ub_shm_comm_t *handle, const message_t *msg);
返回参数成功返回 0;消息已入队但目标 Ring 达到拥塞阈值返回 UB_COMM_SEND_CONGESTED;失败返回负数错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
msgconst message_t *待发送消息非空;消息头字段满足 2.2 中规格

常见返回值

返回值说明
0发送成功,目标 Ring 未处于稳定拥塞
UB_COMM_SEND_CONGESTED发送成功,但目标 Ring 已达到拥塞阈值,调用方可降速
-EINVAL参数错误、优先级非法等
-EOPNOTSUPP发送系统保留消息类型
-EPERMsrc_node_id 与当前节点不一致
-EMSGSIZE消息大小超过目标 Ring 限制
私有负数错误码Ring 满、远端未就绪、目标 Ring 不存在、CAS 重试超限等内部错误

约束与注意事项

  • UB_COMM_SEND_CONGESTED 表示消息已经入队,不是失败。
  • 业务侧不应使用 msg_type 为 0xFF、0xFE、0xFD 的消息。
  • 发送到远端前可使用 ub_comm_queue_check_ready 确认目标节点已就绪。

2.6 ub_comm_queue_get_status ​

项目内容
名称ub_comm_queue_get_status
接口描述查询指定节点、指定优先级 Ring 的流控状态快照。
接口类型函数
函数原型int ub_comm_queue_get_status(ub_shm_comm_t *handle, uint8_t node_id, uint8_t priority, ub_comm_queue_status_t *status);
返回参数成功返回 0;失败返回负数错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
node_iduint8_t待查询节点 ID必须存在于当前节点映射表
priorityuint8_t待查询 Ring 优先级0~7;业务 Ring 为 1~7
statusub_comm_queue_status_t *输出状态快照非空

约束与注意事项

  • 返回的是原子快照,适合维测和流控估计,不提供强一致队列长度语义。
  • 查询不存在的 Ring 或未就绪节点会返回负数错误码。

2.7 ub_comm_queue_set_congestion_threshold ​

项目内容
名称ub_comm_queue_set_congestion_threshold
接口描述设置当前节点本地指定业务 Ring 的拥塞阈值。
接口类型函数
函数原型int ub_comm_queue_set_congestion_threshold(ub_shm_comm_t *handle, uint8_t priority, uint32_t congestion_threshold_percent);
返回参数成功返回 0;失败返回负数错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
priorityuint8_t本地 Ring 优先级必须为 1~7;0 为内部保留,不能配置
congestion_threshold_percentuint32_t拥塞阈值百分比0~100;0 表示所有非满状态都按拥塞处理

约束与注意事项

  • 只更新当前节点本地 Ring。远端生产者写入该 Ring 时会从共享 Ring 对象读取到新阈值。
  • 默认阈值语义可用 80 恢复到常见的 80% 水位。

2.8 ub_comm_queue_config_heartbeat ​

项目内容
名称ub_comm_queue_config_heartbeat
接口描述设置或查询当前通信实例的本地心跳配置。
接口类型函数
函数原型int ub_comm_queue_config_heartbeat(ub_shm_comm_t *handle, const ub_comm_queue_heartbeat_config_t *request, ub_comm_queue_heartbeat_config_t *effective);
返回参数成功返回 0;失败返回负数错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
requestconst ub_comm_queue_heartbeat_config_t *请求设置的心跳配置可为空;非空时字段满足 2.2 中规格
effectiveub_comm_queue_heartbeat_config_t *输出最终生效配置可为空

约束与注意事项

  • request == NULL && effective != NULL 表示只查询当前配置。
  • request != NULL && effective == NULL 表示只设置配置。
  • request != NULL && effective != NULL 表示设置后返回最终生效配置。
  • request 和 effective 不能同时为 NULL。
  • 该接口只影响后台心跳线程,不修改收发热路径。
  • 本节点发布 heartbeat_interval_ms 后,其他节点会用它放大对本节点的实际超时窗口,避免节点间心跳配置不一致导致误判。
  • 本节点观察某个 peer 的实际超时窗口为 max(timeout_ms, peer heartbeat_interval_ms * 3, check_interval_ms * 2)。

使用样例

c
ub_comm_queue_heartbeat_config_t req = {
    .heartbeat_interval_ms = 100,
    .check_interval_ms = 100,
    .timeout_ms = 1000,
};
ub_comm_queue_heartbeat_config_t eff = {0};
int ret = ub_comm_queue_config_heartbeat(&handle, &req, &eff);

2.9 ub_comm_queue_check_ready ​

项目内容
名称ub_comm_queue_check_ready
接口描述查询指定节点是否已完成通信队列初始化。
接口类型函数
函数原型bool ub_comm_queue_check_ready(ub_shm_comm_t *handle, const uint8_t node_id);
返回参数节点就绪返回 true;参数无效、节点未就绪或查询失败返回 false。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
node_iduint8_t待查询节点 ID应存在于节点映射表

约束与注意事项

  • 当前不建议业务依赖该接口完成收包;请优先使用 ub_comm_queue_register_process_func 注册回调。

2.10 ub_comm_queue_register_process_func ​

项目内容
名称ub_comm_queue_register_process_func
接口描述为指定业务消息类型注册处理回调。
接口类型函数
函数原型int ub_comm_queue_register_process_func(ub_shm_comm_t *handle, uint8_t msg_type, ub_func_type_t func_type, ub_callback_t func, void *ctx);
返回参数成功返回 0;失败返回负数错误码。
参数名参数类型参数类型说明参数有效性规格
handleub_shm_comm_t *通信实例句柄指针非空,且 *handle 有效
msg_typeuint8_t消息类型不应为系统保留值 0xFF, 0xFE或 0xFD
func_typeub_func_type_t回调执行方式UB_FUNC_SYNC 或 UB_FUNC_ASYNC
funcub_callback_t回调函数非空
ctxvoid *用户上下文可为空;回调时原样传回

约束与注意事项

  • 同一个 msg_type 重复注册会覆盖旧回调。
  • 已经被分发线程取出或已投递线程池的消息可能仍使用旧回调执行。

通信队列使用样例

c
#include "ub_dist_comm_queue.h"
#include <stdint.h>
#include <stdlib.h>

static void on_msg(const message_t *msg, void *ctx)
{
    (void)ctx;
    /* 处理 msg->body,长度为 msg->header.body_length */
}

int comm_example(void)
{
    void *init_mem = calloc(1, 4096);
    void *ring_mem0 = calloc(1, 1 << 20);
    void *ring_mem1 = calloc(1, 1 << 20);
    ub_ring_region_info_t entries[2] = {
        {.region = {.size = 1 << 20, .ptr = ring_mem0}, .node_id = 0},
        {.region = {.size = 1 << 20, .ptr = ring_mem1}, .node_id = 1},
    };
    ub_ring_region_map_t map = {.entries = entries, .count = 2};
    ub_ring_desc_t desc = {.ring_capacity = 1024, .max_msg_size = 256, .priority = 1};
    ub_comm_conf_t conf = {.cpu_id = -1, .max_nodes = 2, .current_node_id = 0, .num_rings = 1, .ring_descs = &desc};
    ub_shm_area_t init_region = {.size = 4096, .ptr = init_mem};
    ub_shm_comm_t handle = NULL;

    int ret = ub_comm_queue_init(&handle, &init_region, &map, &conf);
    if (ret != 0) {
        return ret;
    }
    ret = ub_comm_queue_register_process_func(&handle, 1, UB_FUNC_SYNC, on_msg, NULL);
    if (ret != 0) {
        (void)ub_comm_queue_deinit(&handle);
        return ret;
    }

    char body[] = "hello";
    message_t msg = {
        .header = {.src_thread_id = 1001, .body_length = (uint32_t)sizeof(body), .dest_node_id = 1,
                   .src_node_id = 0, .msg_type = 1, .priority = 1},
        .body = body,
    };
    ret = ub_comm_queue_send(&handle, &msg);
    (void)ub_comm_queue_deinit(&handle);
    return ret == UB_COMM_SEND_CONGESTED ? 0 : ret;
}

3. 分布式锁 ​

3.1 模块说明 ​

分布式锁模块提供三种锁类型:

  • 分布式读写锁:支持共享锁 S、共享排他锁 SX、排他锁 X,并提供故障恢复、持有者查询和重建能力。
  • 分布式互斥锁:轻量级互斥锁,适合简单的排他访问场景。
  • 分布式自旋锁:基于 CAS 的自旋锁,适合极短临界区场景。

全局约束

  • 共享内存中需为锁对象预留足够空间:
    • 读写锁:UB_RW_LOCK_SIZE = 640 字节
    • 互斥锁:UB_MUTEX_LOCK_SIZE = 384 字节
    • 自旋锁:UB_SPIN_LOCK_SIZE = 64 字节
  • ub_rw_lock_t、ub_mutex_lock_t、ub_spin_lock_t 是不透明共享内存布局类型,调用方不应依赖其内部字段。
  • ub_location_t 用于标识锁调用者,node_id 和 tid 应在业务集群内能唯一定位调用线程或逻辑线程。

3.2 公开数据结构 ​

名称类型说明
time_ms_tuint64_t毫秒时间戳类型
ub_rw_lock_t不透明结构体分布式读写锁共享内存对象
ub_mutex_lock_t不透明结构体分布式互斥锁共享内存对象
ub_spin_lock_t不透明结构体分布式自旋锁共享内存对象

ub_lock_mode_t ​

名称值说明
UB_LOCK_S0共享锁,读锁
UB_LOCK_SX1共享排他锁,升级意图锁
UB_LOCK_X2排他锁,写锁
UB_LOCK_I3无效锁类型

ub_lock_result_t ​

名称值说明
UB_LOCK_SUCCESS0操作成功
UB_LOCK_TIMEOUT1加锁或等待超时
UB_LOCK_CONFLICT2锁冲突
UB_LOCK_ERROR3参数错误或内部错误

锁参数结构 ​

结构体字段类型说明参数有效性规格
ub_location_ttidint32_t线程 ID 或业务逻辑线程 ID同一节点内应能唯一标识调用者
ub_location_tnode_iduint8_t逻辑节点 ID应与通信/锁集群节点 ID 一致
ub_lock_policy_ttimeout_tstime_ms_t绝对超时时间,单位ms传入 NULL 策略时使用默认值 10000
ub_lock_policy_tallow_delay_releasebool是否允许延迟释放传入 NULL 策略时默认 false
ub_lock_policy_trecursivebool是否允许递归加锁传入 NULL 策略时默认 false
ub_lock_config_tlease_timetime_ms_t分布式锁租约时长传入 NULL 配置时默认 60000
ub_lock_config_theartbeat_timeouttime_ms_t心跳超时阈值传入 NULL 配置时默认 500
ub_lock_query_result_tnode_iduint8_t被查询节点 ID由查询接口填充
ub_lock_query_result_theld_modeub_lock_mode_t该节点可恢复的持锁模式输出字段
ub_lock_query_result_tholder_tidint32_tX/SX 模式下的持有者线程 ID输出字段
ub_lock_query_result_trecursive_countuint32_tX/SX 模式下递归计数输出字段
ub_lock_query_result_treserve_modeub_lock_mode_t延迟释放保留模式输出字段
ub_lock_rebuild_info_tquery_resultsconst ub_lock_query_result_t *各节点查询结果数组重建时非空,长度为 query_result_count
ub_lock_rebuild_info_tquery_result_countuint32_t查询结果数量重建时应与数组元素数量一致

3.3 ub_rw_lock_create ​

项目内容
名称ub_rw_lock_create
接口描述初始化共享内存中的分布式读写锁对象。
接口类型函数
函数原型void ub_rw_lock_create(ub_rw_lock_t *lock, const ub_lock_config_t *config, const ub_location_t *location);
返回参数无。参数无效时直接返回。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空;指向至少 UB_RW_LOCK_SIZE 字节共享内存
configconst ub_lock_config_t *锁配置可为空;为空时使用默认配置
locationconst ub_location_t *调用者位置非空

3.4 ub_rw_lock_free ​

项目内容
名称ub_rw_lock_free
接口描述释放调用节点与该锁关联的本地资源。
接口类型函数
函数原型void ub_rw_lock_free(ub_rw_lock_t *lock, const ub_location_t *location);
返回参数无。参数无效时直接返回。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空
locationconst ub_location_t *调用者位置非空

3.5 加锁接口 ​

项目内容
名称ub_rw_lock_s_lock、ub_rw_lock_x_lock、ub_rw_lock_sx_lock
接口描述分别申请共享锁、排他锁、共享排他锁。
接口类型函数
函数原型ub_lock_result_t ub_rw_lock_s_lock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
函数原型ub_lock_result_t ub_rw_lock_x_lock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
函数原型ub_lock_result_t ub_rw_lock_sx_lock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
返回参数返回 ub_lock_result_t。参数无效返回 UB_LOCK_ERROR;策略为空时使用默认策略。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空,且已通过 ub_rw_lock_create 初始化
policyconst ub_lock_policy_t *本次加锁策略可为空;为空使用默认策略
locationconst ub_location_t *调用者位置非空

约束与注意事项

  • recursive == false 时,同一调用者重复申请同类锁可能按冲突或错误处理。
  • 调用方应使用与加锁模式匹配的解锁接口释放。

3.6 解锁接口 ​

项目内容
名称ub_rw_lock_s_unlock、ub_rw_lock_x_unlock、ub_rw_lock_sx_unlock
接口描述分别释放共享锁、排他锁、共享排他锁。
接口类型函数
函数原型ub_lock_result_t ub_rw_lock_s_unlock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
函数原型ub_lock_result_t ub_rw_lock_x_unlock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
函数原型ub_lock_result_t ub_rw_lock_sx_unlock(ub_rw_lock_t *lock, const ub_lock_policy_t *policy, const ub_location_t *location);
返回参数返回 ub_lock_result_t。参数无效返回 UB_LOCK_ERROR;策略为空时使用默认策略。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空,且已初始化
policyconst ub_lock_policy_t *本次释放策略可为空;为空使用默认策略
locationconst ub_location_t *调用者位置非空,且应与持锁者匹配

约束与注意事项

  • 释放未持有的锁、释放模式不匹配或调用者不匹配可能返回 UB_LOCK_ERROR 或 UB_LOCK_CONFLICT。

3.7 ub_rw_lock_recover ​

项目内容
名称ub_rw_lock_recover
接口描述对异常失败进程持有或半写入的锁状态进行恢复清理。
接口类型函数
函数原型ub_lock_result_t ub_rw_lock_recover(ub_rw_lock_t *lock, const uint32_t process_id, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;参数无效或恢复失败返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空,且已初始化
process_iduint32_t待恢复的进程或节点标识应与故障持有者的标识匹配
locationconst ub_location_t *执行恢复的调用者位置非空

3.8 ub_rw_lock_query_holder ​

项目内容
名称ub_rw_lock_query_holder
接口描述查询本节点用于锁重建的最小持有者状态。
接口类型函数
函数原型ub_lock_result_t ub_rw_lock_query_holder(ub_rw_lock_t *lock, const ub_location_t *location, ub_lock_query_result_t *result);
返回参数成功返回 UB_LOCK_SUCCESS;参数无效返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_rw_lock_t *共享内存锁对象地址非空,且已初始化
locationconst ub_location_t *调用者位置非空
resultub_lock_query_result_t *输出查询结果非空

3.9 ub_rw_lock_rebuild ​

项目内容
名称ub_rw_lock_rebuild
接口描述根据集群各节点查询结果,在新的共享内存锁对象上重建锁状态。
接口类型函数
函数原型ub_lock_result_t ub_rw_lock_rebuild(ub_rw_lock_t *old_lock, ub_rw_lock_t *new_lock, const ub_lock_rebuild_info_t *rebuild_info, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;参数无效或重建失败返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
old_lockub_rw_lock_t *旧共享内存锁对象地址非空
new_lockub_rw_lock_t *新共享内存锁对象地址非空,指向可写共享内存
rebuild_infoconst ub_lock_rebuild_info_t *聚合后的查询结果非空;query_results 和 query_result_count 应匹配
locationconst ub_location_t *执行重建的调用者位置非空

3.10 分布式互斥锁接口 ​

ub_mutex_lock_create ​

项目内容
名称ub_mutex_lock_create
接口描述初始化分布式互斥锁。
接口类型函数
函数原型void ub_mutex_lock_create(ub_mutex_lock_t *lock);
返回参数无。参数无效时直接返回。
参数名参数类型参数类型说明参数有效性规格
lockub_mutex_lock_t *共享内存互斥锁对象地址非空;指向至少 UB_MUTEX_LOCK_SIZE 字节共享内存

ub_mutex_lock_free ​

项目内容
名称ub_mutex_lock_free
接口描述释放分布式互斥锁关联资源。
接口类型函数
函数原型void ub_mutex_lock_free(ub_mutex_lock_t *lock);
返回参数无。参数无效时直接返回。
参数名参数类型参数类型说明参数有效性规格
lockub_mutex_lock_t *共享内存互斥锁对象地址非空

ub_mutex_lock ​

项目内容
名称ub_mutex_lock
接口描述获取分布式互斥锁。
接口类型函数
函数原型ub_lock_result_t ub_mutex_lock(ub_mutex_lock_t *lock, time_ms_t timeout_ms, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;超时返回 UB_LOCK_TIMEOUT;参数无效返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_mutex_lock_t *共享内存互斥锁对象地址非空,且已通过 ub_mutex_lock_create 初始化
timeout_mstime_ms_t超时时间,单位ms0 表示使用默认值 10000ms
locationconst ub_location_t *调用者位置非空

ub_mutex_unlock ​

项目内容
名称ub_mutex_unlock
接口描述释放分布式互斥锁。
接口类型函数
函数原型ub_lock_result_t ub_mutex_unlock(ub_mutex_lock_t *lock, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;参数无效或调用者不匹配返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_mutex_lock_t *共享内存互斥锁对象地址非空,且已初始化
locationconst ub_location_t *调用者位置非空,且应与持锁者匹配

3.11 分布式自旋锁接口 ​

ub_spin_lock_init ​

项目内容
名称ub_spin_lock_init
接口描述初始化分布式自旋锁。
接口类型函数
函数原型void ub_spin_lock_init(ub_spin_lock_t *lock);
返回参数无。参数无效时直接返回。
参数名参数类型参数类型说明参数有效性规格
lockub_spin_lock_t *共享内存自旋锁对象地址非空;指向至少 UB_SPIN_LOCK_SIZE 字节共享内存

ub_spin_lock ​

项目内容
名称ub_spin_lock
接口描述获取分布式自旋锁。
接口类型函数
函数原型ub_lock_result_t ub_spin_lock(ub_spin_lock_t *lock, time_ms_t timeout_ms, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;超时返回 UB_LOCK_TIMEOUT;参数无效返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_spin_lock_t *共享内存自旋锁对象地址非空,且已通过 ub_spin_lock_init 初始化
timeout_mstime_ms_t超时时间,单位ms0 表示使用默认值 10000ms
locationconst ub_location_t *调用者位置非空

ub_spin_unlock ​

项目内容
名称ub_spin_unlock
接口描述释放分布式自旋锁。
接口类型函数
函数原型ub_lock_result_t ub_spin_unlock(ub_spin_lock_t *lock, const ub_location_t *location);
返回参数成功返回 UB_LOCK_SUCCESS;参数无效或调用者不匹配返回 UB_LOCK_ERROR。
参数名参数类型参数类型说明参数有效性规格
lockub_spin_lock_t *共享内存自旋锁对象地址非空,且已初始化
locationconst ub_location_t *调用者位置非空,且应与持锁者匹配

3.12 分布式锁使用样例 ​

c
#include <stdbool.h>
#include "ub_dist_lock.h"
#include <stdlib.h>

void rw_lock_example(void)
{
    ub_rw_lock_t *lock = (ub_rw_lock_t *)calloc(1, UB_RW_LOCK_SIZE);
    ub_location_t loc = {.tid = 1001, .node_id = 1};
    ub_lock_config_t config = {.lease_time = 60000, .heartbeat_timeout = 500};
    ub_lock_policy_t policy = {.timeout_ts = 10000, .allow_delay_release = false, .recursive = false};

    ub_rw_lock_create(lock, &config, &loc);
    if (ub_rw_lock_x_lock(lock, &policy, &loc) == UB_LOCK_SUCCESS) {
        /* 临界区 */
        (void)ub_rw_lock_x_unlock(lock, &policy, &loc);
    }
    ub_rw_lock_free(lock, &loc);
    free(lock);
}

void mutex_lock_example(void)
{
    ub_mutex_lock_t *lock = (ub_mutex_lock_t *)calloc(1, UB_MUTEX_LOCK_SIZE);
    ub_location_t loc = {.tid = 1001, .node_id = 1};

    ub_mutex_lock_create(lock);
    if (ub_mutex_lock(lock, 10000, &loc) == UB_LOCK_SUCCESS) {
        /* 临界区 */
        (void)ub_mutex_unlock(lock, &loc);
    }
    ub_mutex_lock_free(lock);
    free(lock);
}

void spin_lock_example(void)
{
    ub_spin_lock_t *lock = (ub_spin_lock_t *)calloc(1, UB_SPIN_LOCK_SIZE);
    ub_location_t loc = {.tid = 1001, .node_id = 1};

    ub_spin_lock_init(lock);
    if (ub_spin_lock(lock, 10000, &loc) == UB_LOCK_SUCCESS) {
        /* 临界区(应极短) */
        (void)ub_spin_unlock(lock, &loc);
    }
    free(lock);
}

4. 分布式事务资源 ​

4.1 模块说明 ​

事务资源接口把调用方传入的 uint64_t 内存地址视作一个共享原子值,提供初始化、设置、读取和原子加法能力。

名称值说明
UB_RES_OK0操作成功
UB_RES_ERROR-1操作失败

通用参数有效性规格

  • handle 必须非空。
  • handle 地址必须满足 uint64_t 对齐要求,当前实现按 8 字节对齐检查。
  • 输出参数如 out_val 必须非空。
  • 调用方负责保证 handle 指向的内存在所有参与方之间可见,并在使用期间保持有效。

4.2 ub_dist_tx_res_init ​

项目内容
名称ub_dist_tx_res_init
接口描述初始化事务资源原子值,将目标值置为 0。
接口类型函数
函数原型int ub_dist_tx_res_init(uint64_t *handle);
返回参数成功返回 UB_RES_OK;参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *共享原子值地址非空,且 8 字节对齐

4.3 ub_dist_tx_res_set ​

项目内容
名称ub_dist_tx_res_set
接口描述设置事务资源原子值。
接口类型函数
函数原型int ub_dist_tx_res_set(uint64_t *handle, uint64_t value);
返回参数成功返回 UB_RES_OK;参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *共享原子值地址非空,且 8 字节对齐
valueuint64_t待设置值任意 uint64_t 值

4.4 ub_dist_tx_res_get ​

项目内容
名称ub_dist_tx_res_get
接口描述读取事务资源当前值。
接口类型函数
函数原型int ub_dist_tx_res_get(uint64_t *handle, uint64_t *out_val);
返回参数成功返回 UB_RES_OK 并写入 *out_val;参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *共享原子值地址非空,且 8 字节对齐
out_valuint64_t *输出读取值非空

4.5 ub_dist_tx_res_fetch_add ​

项目内容
名称ub_dist_tx_res_fetch_add
接口描述对事务资源执行原子加法,并返回加法前的旧值。
接口类型函数
函数原型int ub_dist_tx_res_fetch_add(uint64_t *handle, uint64_t value, uint64_t *out_val);
返回参数成功返回 UB_RES_OK 并将旧值写入 *out_val;参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *共享原子值地址非空,且 8 字节对齐
valueuint64_t原子增加值任意 uint64_t 值,溢出按无符号整数规则回绕
out_valuint64_t *输出加法前旧值非空

4.6 ub_fence_order_t 枚举 ​

名称值ARM64 指令说明
UB_FENCE_RELAXED0(无硬件指令)仅编译器屏障,阻止寄存器缓存和编译器重排
UB_FENCE_ACQUIRE1dmb ishldAcquire:后续读不可前移
UB_FENCE_RELEASE2dmb ishstRelease:先前写不可后移
UB_FENCE_ACQ_REL3dmb ishAcquire-Release:双向屏障
UB_FENCE_SEQ_CST4dsb ishSequential Consistency:全局一致序

4.7 ub_dist_tx_res_fence ​

项目内容
名称ub_dist_tx_res_fence
接口描述统一内存屏障接口。根据 order 参数插入对应强度的编译器屏障和硬件屏障。所有变体均包含 compiler barrier("memory" clobber),可阻止编译器寄存器缓存和跨点重排。
接口类型函数
函数原型int ub_dist_tx_res_fence(ub_fence_order_t order);
返回参数成功返回 UB_RES_OK;order 超出合法范围返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
orderub_fence_order_t屏障语义UB_FENCE_RELAXED ~ UB_FENCE_SEQ_CST

约束与注意事项

  • 线程安全:是(fence 仅约束调用线程自身的内存访问序)。
  • 幂等性:连续多次调用等价于单次对应屏障。
  • UB_FENCE_RELAXED 仅生成编译器屏障(asm volatile("" ::: "memory")),不产生任何硬件 fence 指令,适用于仅需阻止编译器优化而无需硬件保序的场景。

4.10 ub_dist_tx_res_add ​

项目内容
名称ub_dist_tx_res_add
接口描述对分布式事务资源执行原子加法(无 fetch 版本),将 value 原子地加到 handle 指向的共享内存位置,不返回旧值。使用 memory_order_release 语义,适用于 MPI_Accumulate(MPI_SUM) 等仅需累加不需旧值的场景。
接口类型函数
函数原型int ub_dist_tx_res_add(uint64_t *handle, uint64_t value);
返回参数成功返回 UB_RES_OK;handle 为 NULL 或地址未 8 字节对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *指向目标共享内存位置的指针非空,且 8 字节对齐
valueuint64_t要累加的 64 位无符号整数值任意 uint64_t 值,溢出按无符号整数规则回绕

约束与注意事项

  • 与 ub_dist_tx_res_fetch_add 的区别:本接口不返回旧值,硬件可优化为更轻量的指令(ARM64: STADD vs LDADD);使用 release 语义(fetch_add 使用 acq_rel),因无需读回的 acquire 保证。
  • 加法为 uint64_t 模算术,溢出时回绕(wrap-around),不产生错误。
  • 若需要获取加法以前的旧值,请使用 ub_dist_tx_res_fetch_add。

4.11 ub_dist_tx_res_fetch_xor ​

项目内容
名称ub_dist_tx_res_fetch_xor
接口描述对分布式事务资源执行原子异或并返回旧值。将 value 与 handle 指向的共享内存位置原子地进行 XOR 操作,返回操作前的旧值。使用 memory_order_acq_rel 语义。
接口类型函数
函数原型int ub_dist_tx_res_fetch_xor(uint64_t *handle, uint64_t value, uint64_t *out_val);
返回参数成功返回 UB_RES_OK 并将旧值写入 *out_val;参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *指向目标共享内存位置的指针非空,且 8 字节对齐
valueuint64_t要异或的 64 位无符号整数值任意 uint64_t 值
out_valuint64_t *输出异或前的旧值非空

约束与注意事项

  • 异或操作为按位 XOR,满足自反性:a ^ b ^ b == a,可用于无锁标志位翻转。
  • 使用 acq_rel 语义,同时具备 acquire 和 release 保证。

4.12 ub_dist_tx_res_compare_exchange ​

项目内容
名称ub_dist_tx_res_compare_exchange
接口描述对分布式事务资源执行原子比较并交换(CAS)。如果 handle 指向的值等于 *expected,则原子地将其替换为 desired,返回成功;否则将当前值写入 *expected,返回失败。使用 memory_order_acq_rel(成功)/ memory_order_acquire(失败)语义。
接口类型函数
函数原型int ub_dist_tx_res_compare_exchange(uint64_t *handle, uint64_t *expected, uint64_t desired, int *success);
返回参数函数调用成功返回 UB_RES_OK(注意:success 的值表示 CAS 是否匹配,而非函数调用是否成功);参数无效或地址未对齐返回 UB_RES_ERROR。
参数名参数类型参数类型说明参数有效性规格
handleuint64_t *指向目标共享内存位置的指针非空,且 8 字节对齐
expecteduint64_t *输入为期望值,失败时输出当前实际值非空
desireduint64_t期望匹配时要写入的新值任意 uint64_t 值
successint *输出 CAS 是否成功(1=成功,0=失败)非空

约束与注意事项

  • CAS 失败时,*expected 会被更新为当前实际值,调用方可据此重试。
  • 使用 compare_exchange_strong 语义,不会发生伪失败(spurious failure)。
  • 典型用法:自旋锁、无锁队列、状态机转换等需要原子条件更新的场景。

4.13 事务资源使用样例 ​

c
#include "ub_dist_tx_res.h"
#include <stdint.h>

int tx_res_example(void)
{
    uint64_t value = 0;
    uint64_t old_value = 0;

    if (ub_dist_tx_res_init(&value) != UB_RES_OK) {
        return -1;
    }
    if (ub_dist_tx_res_set(&value, 99) != UB_RES_OK) {
        return -1;
    }
    if (ub_dist_tx_res_fetch_add(&value, 1, &old_value) != UB_RES_OK) {
        return -1;
    }
    /* old_value == 99, value == 100 */

    /* fetch_xor: 0x64 ^ 0x0F = 0x6B, 旧值 0x64 */
    if (ub_dist_tx_res_fetch_xor(&value, 0x0F, &old_value) != UB_RES_OK) {
        return -1;
    }

    /* compare_exchange: 期望 0x6B 匹配,替换为 200 */
    uint64_t expected = 0x6B;
    int success = 0;
    if (ub_dist_tx_res_compare_exchange(&value, &expected, 200, &success) != UB_RES_OK) {
        return -1;
    }
    /* success == 1, value == 200 */

    /* fence: release + acquire 配对保证可见性 */
    ub_dist_tx_res_fence(UB_FENCE_RELEASE);
    ub_dist_tx_res_fence(UB_FENCE_ACQUIRE);

    return ub_dist_tx_res_get(&value, &old_value);
}

5. 接入建议 ​

  • 通信队列和分布式锁均依赖调用方提供共享内存,调用方应统一管理共享内存创建、映射、清零和生命周期。
  • 业务消息类型和 Ring 优先级建议集中定义,避免与系统保留值冲突。
  • 对外接口多以指针参数表达共享状态,调用前应显式校验非空、对齐、长度和节点 ID 范围。
  • 对于发送接口,调用方应区分“发送失败”和“发送成功但拥塞提示”:UB_COMM_SEND_CONGESTED 不应被当作失败重发。
  • 多进程场景下,所有参与方应使用相同版本的头文件和库文件,避免共享内存布局不一致。