本节主要介绍下IPC的其他几个模块,主要包含
(1)Heap*MP堆模块
(2)ListMP链表模块
(3)GateMP门模块
(4)MultiProc多核管理模块
一、Heap*MP模块
Heap*MP 模块主要有三类模块:
HeapBufMP:固定大小的内存管理器,其分配的所有缓冲区都是一样的,当然也可以通过不同HeapBufMP实例来管理不同的大小的缓冲区。
HeapMultiBufMP:每个HeapMultiBufMP支持8个不同大小的缓冲区。当一个分配需求被发送,HeapMultiBufMP的实例从不同大小的待分配缓冲区中,选择一个能满足要求的最小缓冲区。如果待分配缓冲区为空,那么这个分配就失败了。
HeapMemMP:这是个能分配变长大小的内存管理器。另外HeapMemMP管理共享内存区(Shared memory)的一个缓冲区。
(1)动态创造一个Heap*MP实例
使用Heap*MP_create()函数可以动态地创造一个Heap*MP实例,如同其他IPC模块一样,在创建实例之前,需要初始化参数Heap*MP_Params结构。当创建实例时,共享内存也会被初始化,而实例对象本身却在本地内存中被创建,只有实际缓存和一些共享信息仍残存在共享内存中。
Heap*MP_Params结构的相关参数设置
regionID:分配共享内存的共享区域的序号
name:Heap实例的名字
align:每个块的对齐参数
numBlocks:固定大小块的数目
blockSize:实例中块的大小
gate:用于保护上下文的多处理门
exact:只有当请求分配的大小同块精确匹配时,对分配一个块
(2)打开一个Heap*MP实例
一旦一个Heap*MP实例在一个处理上被创建,那么通过对应相同的共享实例的本地句柄,另一个处理器也可以打开这个Heap,这个远程处理器通过Heap*MP_open()来打开实例。利用NameServer实例,远程处理器通过Heap*MP的名称来区分不同实例,并找到Heap实例地址
Heap*MP_open()通过Heap名称(Heap*MP_Params中设置)来找到Heap*MP实例,并将其对应一个本地的Heap*MP句柄。
(3)关闭一个Heap*MP实例
通过Heap*MP_close()来释放存储在本地内存的Heap*MP实例,只有当前线程已经打开Heap*MP实例并且其他线程没有调用Heap*MP_delete()时,才能使用Heap*MP_close()函数
(4)删除一个Heap*MP实例
创造Heap*MP实例的线程可能通过Heap*MP_delete()函数来释放存储在本地内存中的Heap*MP对象,并标明此Heap所在共享内存区不再被初始化。由此可以看出,delete()函数是同create()函数对应的,而close()函数是同Open()函数对应的
(5)从堆中分配内存
HeapBufMP_alloc函数可以从堆Heap空闲表中获得第一个缓冲区
而HeapMultiMP_alloc函数从不同大小的待分配缓冲区中,选择一个能满足要求的最小缓冲区。
HeapMemMP_alloc函数可以从堆中分配一个请求大小的缓冲区
对于所有的三类函数,消息的高速缓存一致性都是通过共享区域模块(ShareRegion)来管理的
通过Heap*MP_free()来释放三类函数分配的内存
同Heap*MP实例不同,从堆中分配内存是统一保存在共享区域中的堆中,所以内存分配和释放不一定需要在同一个线程中完成,而Heap*MP实例是保存在本地处理器中的,所以其创建和删除是在同一个处理器线程中完成的。
二、GateMP模块
GateMP模块是用于本地和远程处理器的上下文保护的,进入一个GateMP模块,可以避免在同一处理器其他线程抢占,同时也避免了远程处理器进入相同的门。GateMP模块通常的用法是用于保护对于共享资源的读写操作。
(1)动态创建GateMP实例
首先需要初始化GateMP实例参数GateMP_Params
a). 远程处理器保护方式设置:remoteProtect选项可以设置为:
GateMP_RemoteProtect_NONE:只创建本地门保护
GateMP_RemoteProctect_SYSTEM:(默认)
b). 本地处理理器保护方式设置:localProtect选项可以设置为:
GateMP_LocalProtect_NONE:不支持任何的本地上下保护,一般用于单线程的本地应用。
GateMP_LocalProtect_INTERRUPT:使用SYS/BIOS GateHwi来实施,由此来避免硬件中断
GateMP_LocalProtect_TASK
LET:使用SYS/BIOS GateSwi来实施,由此来避免软件中断
GateMP_LocalProtect_THREAD:使用SYS/BIOS GateMutexPri(基于信号量模块的)来实施
c). name:名称
d). regionID:分配Gate实例的共享区域SharedRegion的ID
(2)打开Gate实例
一旦处理器创建一个GateMP实例,其他处理器可以一个指向相同实例的本地句柄来找开这个实例了
GateMP模块也是通过NameServer实例来允许一个远程处理器来指向本地Gate实例
关闭实例是利用GateMP_close()实例的
(3)进入GateMP实例
通过GateMP_enter()来进入一个门,这个函数进入了调用线程的本地门,当进入该门后,该本地门那被阻塞,如果此门已被远程处理器进入,那么GateMP_enter函数将自旋,直到远程处理器离开此门。
GateMP_enter()返回一个“key”,而这个"key"将被GateMP_leave()用于离开此门
三、List模块
这个模块是用于支持链表对象而设置的,这个链表被设置为双链表形式,所以链表中的元素,可以从链表中的任意上被插入或删除,另外链表没有最大大小的限制。
(1)链表中先入先出设置
要组成一个链表,首先需要一个链表元素类型List_Elem,另外还需要一个头,通过List_put()来在链表尾上增加元素,而通过list_get()来移除并返回链表头上的元素,这个一个典型的先入先出的队列
(2)链表中的迭代
List_next()下一个元素
List_prev()上一个元素
使用:
(3)插入和删除链表元素
另外一种后入先出的栈结构方法是利用:List_putHead()和List_get()函数
四、MultiProc模块
在多核环境下,许多IPC模块都需要区分当前处理器,而MultiProc模块就是用于管理处理器ID的
(1)设置处理器ID
静态设置(在.cfg文件中设置):MultiProc.setConfig();
动态设置:MultiProc_setLocalId(Id);
(2)获得ID
MultiProc_getId("name")根据处理器的名称获得Id
MultiProc_self()返回当前处理器Id
MultiProc_getname(Id)获得处理器名称
(3)不同类处理器:这里的类指的是系统中共享同样内存的一组处理器,如果系列中有多组处理器芯片,可以通过MultiProc.baseIdOfCluster及MultiProc.numProcessors来设置不同处理器芯片,比如如果我们有两个C6678芯片,每个芯片都有8个核心,我们可以如下设置
而Ipc_start()及Ipc_attach()只能用于连接或同步相同类的处理核心
因此为创建一个在多个类(clusters)之间的核连接,我们可以人工地利用MessageQ和NameServerMessageQ模块来创建,
NameServerMessageQ模块支持不同类之间通过MessageQ来进行NameServer请求,
要创建一个不同类之间的核链接,允许调用MessageQ_open()函数,一旦两个核心之间的消息传递被建立,MessageQ可以在两个不同类的核心间使用