编程接口指南

导入端内存段操作

以下列出了导入端操作:

连接操作用于创建 RSM 导入段并与导出的段形成逻辑连接。

对导入的段内存的访问由以下三个接口类别提供:

连接和断开连接内存段

连接到段

int rsm_memseg_import_connect(rsmapi_controller_handle_t controller, rsm_node_id_t node_id, rsm_memseg_id_t segment_id, rsm_permission_t perm, rsm_memseg_import_handle_t *im_memseg);

此函数可用于通过指定的权限 perm 连接到远程节点 node_id 上的段 segment_id。连接到段之后,此函数会返回一个段句柄。

参数 perm 用于指定导入者针对此连接请求的访问模式。要建立连接,可将导出者指定的访问权限与导入者使用的访问模式、用户 ID 和组 ID 进行比较。如果请求模式无效,则会拒绝连接请求。perm 参数限制为以下八进制值:

0400

读取模式

0200

写入模式

0600

读/写模式

指定的控制器必须与用于段导出的控制器具有物理连接。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_CTLR_HNDL

控制器句柄无效

RSMERR_CTLR_NOT_PRESENT

控制器不存在

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_PERM_DENIED

权限被拒绝

RSMERR_SEG_NOT_PUBLISHED_TO_NODE

未将段发布到节点

RSMERR_SEG_NOT_PUBLISHED

未发布此类段

RSMERR_REMOTE_NODE_UNREACHABLE

无法访问远程节点

RSMERR_INTERRUPTED

连接已中断

RSMERR_INSUFFICIENT_MEM

内存不足

RSMERR_INSUFFICIENT_RESOURCES

资源不足

RSMERR_BAD_ADDR

地址错误

断开段连接

int rsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg);

此函数可用于断开段连接。断开段连接之后,此函数将释放段的资源。所有与断开连接的段的现有映射都将删除。句柄 im_memseg 将会释放。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_SEG_STILL_MAPPED

仍映射段

RSMERR_POLLFD_IN_USE

pollfd 正在使用

内存访问元语

以下接口提供了一种机制,用于在 8 位和 64 位数据之间进行传送。get 接口使用重复计数 (rep_cnt) 来表示进程将从连续位置读取的给定大小的数据项数。这些位置从导入的段中的字节偏移 offset 开始。数据会写入从 datap 开始的连续位置。put 接口可使用重复计数 (rep_cnt)。此计数表示进程将从连续位置读取的数据项数。这些位置从 datap 开始。然后,数据会写入已导入段中的连续位置。这些位置从 offset 参数所指定的字节偏移开始。

如果源与目标具有不兼容的字节存储顺序特征,则这些接口还可提供字节交换功能。

函数原型:

int rsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg, off_t offset, uint8_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg, off_t offset, uint16_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg, off_t offset, uint32_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg, off_t offset, uint64_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg, off_t offset, uint8_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg, off_t offset, uint16_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg, off_t offset, uint32_t *datap, ulong_t rep_cnt);
int rsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg, off_t offset, uint64_t *datap, ulong_t rep_cnt);

以下接口用于进行规模大于段访问操作所支持范围的数据传送。

放置段

int rsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg, off_t offset, void *src_addr, size_t length);

此函数可用于将数据从 src_addrlength 所指定的本地内存复制到句柄和偏移所指定的对应导入的段所在位置。

获取段

int rsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg, off_t offset, void *dst_addr, size_t length);

此函数类似于 rsm_memseg_import_put(),但是数据从导入的段流入 dest_vec 参数所定义的本地区域。

putget 例程从参数 offset 所指定的字节偏移位置写入或读取指定的数据量。这些例程从段的基地址开始。偏移必须在相应的边界对齐。例如,rsm_memseg_import_get64() 要求 offsetdatap 在双字界对齐,而 rsm_memseg_import_put32() 则要求偏移在单字边界对齐。

缺省情况下,段的屏障 (barrier) 模式属性为 implicit。 隐式屏障 (barrier) 模式表示调用方假设数据传送在从操作返回时已完成或失败。 由于缺省屏障 (barrier) 模式为隐式,因此应用程序必须初始化屏障 (barrier)。使用缺省模式时,应用程序会在调用 putget 例程之前使用 rsm_memseg_import_init_barrier() 函数初始化屏障 (barrier)。要使用显式操作模式,调用方必须使用屏障 (barrier) 操作来强制完成传送。强制完成传送之后,调用方必须确定强制完成是否产生了任何错误。


注 –

通过在 rsm_memseg_import_map() 例程中传递偏移可以部分映射导入段。如果部分映射了导入段,则 putget 例程中的 offset 参数是相对于段的基地址。用户必须确保将正确的字节偏移传递给 putget 例程。


返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_ADDR

地址错误

RSMERR_BAD_MEM_ALIGNMENT

内存对齐无效

RSMERR_BAD_OFFSET

偏移无效

RSMERR_BAD_LENGTH

长度无效

RSMERR_PERM_DENIED

权限被拒绝

RSMERR_BARRIER_UNINITIALIZED

未初始化屏障 (barrier)

RSMERR_BARRIER_FAILURE

I/O 完成错误

RSMERR_CONN_ABORTED

连接异常中止

RSMERR_INSUFFICIENT_RESOURCES

资源不足

分散/集中访问

rsm_memseg_import_putv()rsm_memseg_import_getv() 函数允许使用 I/O 请求列表来替代单个源地址和单个目标地址。

函数原型:

int rsm_memseg_import_putv(rsm_scat_gath_t *sg_io);
int rsm_memseg_import_getv(rsm_scat_gath_t *sg_io);

使用分散/集中列表的 I/O 向量部分 (sg_io) 可以指定本地虚拟地址或 local_memory_handles。句柄是一种重复使用本地地址范围的有效方法。在释放句柄之前,已分配的系统资源(如已锁定的本地内存)会一直保留。句柄的支持函数包括 rsm_create_localmemory_handle()rsm_free_localmemory_handle()

可以将虚拟地址或句柄收集到向量中,以便写入单个远程段。另外,还可以将从单个远程段读取的结果分散到虚拟地址或句柄的向量中。

整个向量的 I/O 会在返回之前启动。导入段的屏障 (barrier) 模式属性可确定 I/O 是否在函数返回之前已完成。将屏障 (barrier) 模式属性设置为 implicit 可保证数据传送按照在向量中的输入顺序完成。在每个列表项开始时会执行隐式屏障 (barrier) 打开,在每个列表项结束时会执行隐式屏障 (barrier) 关闭。如果检测到错误,向量的 I/O 会终止并且函数会立即返回。剩余计数表示其 I/O 尚未完成或尚未启动的项数。

可以指定在 putvgetv 操作成功时,向目标段发送通知事件。要指定传送通知事件,请在 rsm_scat_gath_t 结构的 flags 项中指定 RSM_IMPLICIT_SIGPOST 值。flags 项还可以包含值 RSM_SIGPOST_NO_ACCUMULATE,该值在设置了 RSM_IMPLICIT_SIGPOST 的情况下会传递给信号传递操作。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SGIO

分散/集中结构指针无效

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_CTLR_HNDL

控制器句柄无效

RSMERR_BAD_ADDR

地址错误

RSMERR_BAD_OFFSET

偏移无效

RSMERR_BAD_LENGTH

长度无效

RSMERR_PERM_DENIED

权限被拒绝

RSMERR_BARRIER_FAILURE

I/O 完成错误

RSMERR_CONN_ABORTED

连接异常中止

RSMERR_INSUFFICIENT_RESOURCES

资源不足

RSMERR_INTERRUPTED

操作被信号中断

获取本地句柄

int rsm_create_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, rsm_localmemory_handle_t *local_handle, caddr_t local_vaddr, size_t length);

此函数可用于获取本地句柄,以便在后续调用 putvgetv 时用于 I/O 向量。尽快释放句柄可节省系统资源(特别是本地句柄占用的内存),这些资源可能会锁定。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_CTLR_HNDL

控制器句柄无效

RSMERR_BAD_LOCALMEM_HNDL

本地内存句柄无效

RSMERR_BAD_LENGTH

长度无效

RSMERR_BAD_ADDR

地址无效

RSMERR_INSUFFICIENT_MEM

内存不足

释放本地句柄

rsm_free_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, rsm_localmemory_handle_t handle);

此函数可用于释放与本地句柄关联的系统资源。由于进程退出时会释放属于该进程的所有句柄,因此调用此函数可节省系统资源。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_CTLR_HNDL

控制器句柄无效

RSMERR_BAD_LOCALMEM_HNDL

本地内存句柄无效

以下示例说明了主数据结构的定义。


示例 2–1 主数据结构

typedef void *rsm_localmemory_handle_t

typedef struct {

   ulong_t	io_request_count;	number of rsm_iovec_t entries

   ulong_t	io_residual_count;	rsm_iovec_t entries not completed 



   in	flags;      

   rsm_memseg_import_handle_t		remote_handle; opaque handle for

                                                    import segment

   rsm_iovec_t							*iovec;		  pointer to

                                                    array of io_vec_t

} rsm_scat_gath_t;



typedef struct {

   int	io_type;		HANDLE or VA_IMMEDIATE

   union {

        rsm_localmemory_handle_t	handle;			used with HANDLE

        caddr_t						virtual_addr;		used with

                                                         VA_IMMEDIATE

    } local;

   size_t          local_offset;		       offset from handle base vaddr

   size_t          import_segment_offset;    offset from segment base vaddr

   size_t          transfer_length; 

} rsm_iovec_t; 

段映射

映射操作只能用于本机体系结构互连,如 Dolphin-SCI 或 NewLink。映射段可授予 CPU 内存操作访问该段的权限,从而节省了调用内存访问元语的开销。

导入段映射

int rsm_memseg_import_map(rsm_memseg_import_handle_t im_memseg, void **address, rsm_attribute_t attr, rsm_permission_t perm, off_t offset, size_t length);

此函数可用于将导入的段映射成调用方地址空间。如果指定了属性 RSM_MAP_FIXED,则此函数会在 **address 中指定的值所在位置映射段。

typedef enum {

RSM_MAP_NONE = 0x0,   /* system will choose available virtual address */

RSM_MAP_FIXED = 0x1,  /* map segment at specified virtual address */

} rsm_map_attr_t;

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_ADDR

地址无效

RSMERR_BAD_LENGTH

长度无效

RSMERR_BAD_OFFSET

偏移无效

RSMERR_BAD_PERMS

权限无效

RSMERR_SEG_ALREADY_MAPPED

已映射段

RSMERR_SEG_NOT_CONNECTED

未连接段

RSMERR_CONN_ABORTED

连接异常中止

RSMERR_MAP_FAILED

映射时出现错误

RSMERR_BAD_MEM_ALIGNMENT

地址未在页边界上对齐

取消映射段

int rsm_memseg_import_unmap(rsm_memseg_import_handle_t im_memseg);

此函数可用于从用户虚拟地址空间中取消映射导入的段。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

屏障 (barrier) 操作

使用屏障 (barrier) 操作可以解决写入访问顺序内存模型问题。屏障 (barrier) 操作还可提供远程内存访问错误检测功能。

屏障 (barrier) 机制由以下操作组成:

打开和关闭操作定义了错误检测和排序的时间间隔。通过初始化操作,可以为每个导入的段创建屏障 (barrier) 并指定屏障 (barrier) 类型。当前支持的唯一屏障 (barrier) 类型针对每个段具有一个时间间隔范围。请使用类型参数值 RSM_BAR_DEFAULT

成功执行关闭操作可保证成功完成所涉及的访问操作,这些操作在屏障 (barrier) 打开操作和屏障 (barrier) 关闭操作之间进行。在屏障 (barrier) 打开操作之后直到屏障 (barrier) 关闭操作之前,不会报告单个数据访问操作(读取和写入)故障。

要在屏障 (barrier) 范围内强制设置特定的写入完成顺序,请使用显式屏障 (barrier) 排序操作。在屏障 (barrier) 排序操作之前发出的写入操作会先于在屏障 (barrier) 排序操作之后发出的操作完成。给定屏障 (barrier) 范围内的写入操作会根据其他屏障 (barrier) 范围进行排序。

初始化屏障 (barrier)

int rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg, rsm_barrier_type_t type, rsmapi_barrier_t *barrier);

注 –

目前,RSM_BAR_DEFAULT 是唯一支持的类型。


返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_BARRIER_PTR

屏障 (barrier) 指针无效

RSMERR_INSUFFICIENT_MEM

内存不足

打开屏障 (barrier)

int rsm_memseg_import_open_barrier(rsmapi_barrier_t *barrier);

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_BARRIER_PTR

屏障 (barrier) 指针无效

关闭屏障 (barrier)

int rsm_memseg_import_close_barrier(rsmapi_barrier_t *barrier);

此函数可用于关闭屏障 (barrier) 并刷新所有存储缓冲区。此调用假设如果调用 rsm_memseg_import_close_barrier() 失败,则调用进程将重试自上次 rsm_memseg_import_open_barrier 调用以来的所有远程内存操作。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_BARRIER_PTR

屏障 (barrier) 指针无效

RSMERR_BARRIER_UNINITIALIZED

未初始化屏障 (barrier)

RSMERR_BARRIER_NOT_OPENED

未打开屏障 (barrier)

RSMERR_BARRIER_FAILURE

内存访问错误

RSMERR_CONN_ABORTED

连接异常中止

排序屏障 (barrier)

int rsm_memseg_import_order_barrier(rsmapi_barrier_t *barrier);

此函数可用于刷新所有存储缓冲区。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_BARRIER_PTR

屏障 (barrier) 指针无效

RSMERR_BARRIER_UNINITIALIZED

未初始化屏障 (barrier)

RSMERR_BARRIER_NOT_OPENED

未打开屏障 (barrier)

RSMERR_BARRIER_FAILURE

内存访问错误

RSMERR_CONN_ABORTED

连接异常中止

销毁屏障 (barrier)

int rsm_memseg_import_destroy_barrier(rsmapi_barrier_t *barrier);

此函数可用于取消分配所有屏障 (barrier) 资源。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

RSMERR_BAD_BARRIER_PTR

屏障 (barrier) 指针无效

设置模式

int rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, rsm_barrier_mode_t mode);

此函数支持可用于 put 例程的可选显式屏障 (barrier) 范围。两种有效的屏障 (barrier) 模式为 RSM_BARRIER_MODE_EXPLICITRSM_BARRIER_MODE_IMPLICIT。屏障 (barrier) 模式的缺省值为 RSM_BARRIER_MODE_IMPLICIT。在隐式模式下,隐式屏障 (barrier) 打开和屏障 (barrier) 关闭会应用于每个 put 操作。将屏障 (barrier) 模式值设置为 RSM_BARRIER_MODE_EXPLICIT 之前,请使用 rsm_memseg_import_init_barrier 例程针对导入的段 im_memseg 初始化屏障 (barrier)。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效

获取模式

int rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, rsm_barrier_mode_t *mode);

此函数可用于获取 put 例程中屏障 (barrier) 范围设置的当前模式值。

返回值:如果成功,则返回 0。否则返回错误值。

RSMERR_BAD_SEG_HNDL

段句柄无效。