您的位置:首页 > 运维架构 > Linux

fusion-linux 简介--转载加翻译

2011-12-02 16:57 211 查看

今天高兴,多发个帖子庆祝,呵呵

1.fusion概述

Fusion是一个IPC-(inter process communication)内核模块。Fusion的哲学是,进程可以仅利用Fusion提供的primivites便可互相“speak”。任何进程可以申请创建primitive实例,所有通过一个ID关联起来的Fusion进程都可访问和使用这个实例。Fusion支持以下几个primivites:

Ø call: 异步(同步)调用其他进程;

Ø ref: 参考值

Ø reactor: 异步事件分发

Ø skirmish: counting lock

Ø property: multi-level locking

Ø shmpool: 共享内存使用管理

并提供/proc文件系统供查看各个primivites的状态。

若干基本概念:

world: fusion用户操作和通信的环境,供clients互相发现对方。比如,Fusion primitives依靠Worldwide ID供识别和使用。每个World有自己的设备节点。Fusion允许多个world同时存在。

fusionee: 指World的参与者。用户空间的每个应用程序进入World会获得一个Fusion ID。一个应用程序获得多个Fusion ID是可能的但不常见。这个Fusion ID用以“target”其他fusionee的句柄。每个world至多只有一个fusionee作为Master,其他的fusionee作为Slave。

Fusion注册为主设备号为250的字符设备,共有/dev/fusion0-7八个设备节点。每个设备节点代表一个独立的Fusion World。

注意,DirectFB项目对fusion的ioctl API进行了封装。

2.fusion API

2.1 打开设备节点

int fd;

fd = open( "/dev/fusion/0", flags );

flags = O_RDWR; defaultvalue.

flags |= O_NONBLOCK;addthisforanon-blockingreadcall.

flags |= O_EXCL; addthistobethe Fusion MasterofthisWorld.

flags |= O_APPEND; addthistobea Fusion SlaveinthisWorld.

EBUSY requesttobe Master,butthis worldalready hasaFusion Master.

EINTR aninterruptoccurred.Nochanges were made.

ENOMEM insufficientkernel memory.

2.2 常用调用—注意没有write 调用

int close( int fd );

ssize_t read( int fd, void *buf, size_t count );

int ioctl( int fd, int request, ... );

void *mmap( void *start, size_t length, int prot,int flags, int fd, off_t offset );

2.2.1 读操作样例

char buf[BUF_SIZE]

char *buf_p = buf;

int fd = open("/dev/fusion/0", O_RDWR |O_NONBLOCK );

int len = read( fd, buf, BUF_SIZE );

while (buf_p < buf + len)

{

FusionReadMessage *header = (FusionReadMessage*)buf_p;

void *data = buf_p + sizeof(FusionReadMessage);

...handle message...

buf_p = data + ((header->msg_size + 3) &~3);

}

2.2.2 ioctl样例

int fd = open("/dev/fusion/0", O_RDWR |O_NONBLOCK );

FusionEnter enter;

...init enter.api...

ret = ioctl( fd, FUSION_ENTER, &enter );

...store fusion_id...

2.2.3 mmap调用

用来创立一块共享区域。通常不超过一个内核页4K大小。同样的一段内存区域会映射到同一个World内的所有Fusionees。第一个mmap调用必须由Fusion Master发起。

2.2.3 返回值

EINVALInputparameterout-of-range.

EFAULTKernelmemoryfault.

EINTRaninterruptoccurred.Nochangeswere made.

读调用的额外返回值:

EMSGSIZEIfthefirstmessagedoesnotfitinthebuffer.

EAGAINForanon-blockingread:nomessagesavailable.

mmap调用的额外返回值:

EPERMFirstmmap notperformedby Fusion Master.

ENOMEMNokernel memoryleft.

2.3 ioctl调用

2.3.1 FUSION_ENTER

ioctl( fd, FUSION_ENTER , FusionEnter )

typedef struct {

struct {

int major; /* [in] */

int minor; /* [in] */

} api;

FusionID fusion_id; /* [out] */

} FusionEnter;

打开设备节点后,利用此调用进入Fusion World。之后,才会获得分配的唯一的句柄:Fusion ID。对所有的slaves,这个调用在Master调用FUSION_UNBLOCK ‘unblock’World之前会一直被‘block’--阻塞。

Major和minor对应关系如下:3.x、4.x、8.x分别对应DirectFB 1.0,1.2和大于1.2的版本。比如我目前的DirectFB-1.4.10-IR-GFX,对应的设置如下:

#define FUSION_API_MAJOR_REQUIRED 8

#define FUSION_API_MINOR_REQUIRED 0

正确调用后,fusion_id会被返回。This fusion_id isFUSION_ID_MASTER for the Master.

返回值:

(除了0, EFAULT and EINTR)

ENOPROTOOPT:不支持的APIversion或者Master使用了不兼容的API version。

2.3.2 FUSION_UNLOCK

供Fusion Master调用,用来unblock Fusion World,从而使得Slaves进入World。

返回值:

(除了0, EFAULT and EINTR)

PERM :不是由 Fusion Master调用。

2.3.2 FUSION_KILL

typedef struct {

FusionID fusion_id;

int signal;

int timeout_ms;

} FusionKill;

用来对其他fusionees发送signal。

Fusion_id对应着目标fusionee。0 means all but ourself 。如果没有与之相对的fusionee,此调用会返回success。

Signal是用来传送的信号,比如SIGTERM、SIGKILL等。

timeout_ms为超市毫秒数设置。-1表示不等待,0表示不限制,换句话说,一直等到至少一个fusionee被terminated。

返回值:

(除了0, EFAULT and EINTR)

ETIMEDOUT:超时。

2.3.3 FUSION_ENTRY_SET_INFO 和FUSION_ENTRY_GET_INFO

typedefstruct {

FusionType type;

int id;

char name[FUSION_ENTRY_INFO_NAME_LENGTH]; /* [in]or [out] */

} FusionEntryInfo;

为Skirmish, Property , Reactor , Ref ,Shmpool存储或读取humanreadable名字。这个名字只用在此ioctl调用和/proc文件系统中。

2.3.4 FUSION_FORK

typedef struct {

FusionID fusion_id;

} FusionFork;

待定。

Perform a ’fork’ of shared memory pools , reactorsand local references.This will copy these entities from fusionee fusion_id to thecalling fusionee.Upon return, fusion_id holds the calling fusionee ID.

Return values are EFAULT or EINTRforfailure,0forsuccess.

2.3.5 FUSION_SEND_MESSAGE

typedef struct {

FusionID fusion_id;

int msg_id;

int msg_channel;

int msg_size;

const void *msg_data;

} FusionSendMessage;

向fusion_id对应的fusionee发送一个Fusion message。对方用read调用来接收此message。接收方可以通过此message解析出发送者的ID。

Msg_id是用户可自定义的msg ID。msg_channel是可选的channel号。Msg_size是msg负载大小[0,65536]。Msg_data指向负载数据,一定不能为空。

返回值:

(除了0, EFAULTand EINTR)

EINVAL: msg_sizet太小(小于0);

EMSGSIZE: msg_sizet太大(大于65536);

ENOMEMkernel: 内存不够,尝试让msg_size小一些;

2.4 IOCTL:CALL primitive

ioctl( fd, FUSION_CALL_NEW , FusionCallNew )

ioctl( fd, FUSION_CALL_EXECUTE , FusionCallExecute)

ioctl( fd, FUSION_CALL_RETURN , FusionCallReturn )

ioctl( fd, FUSION_CALL_DESTROY , int )

2.5 IOCTL:REFprimitive

2.6 IOCTL:SKIRMISHprimitive

2.7 IOCTL:PROPERTYprimitive

2.8 IOCTL:REACTORprimitive

Reactor 模式

2.9 IOCTL:SHMPOOLprimitive

摘抄自李先静的笔记:

在传统的DirectFB应用中,所有的应用程序都在一个进程中,在性能上,有一些优势,然而一个应用程序不稳定会造成整个系统的不稳定。若采用C/S模型,无疑是重蹈XWidnow的覆辙,会丧失性能上的优势。

所以DirectFB采用了另外一种方式,与C/S相区别,称之为主从模型(Master/Slave)。它加了一个称之为fusion的内核模块。Fusion是熔化的意思,多个应用程序在不的进程空间里,通过这个内核模块通信,在这里,一切都溶为一体了。Master应用程序负责初始化一个称为竟技场的东西,其它Slave应用程序可以加入或者退出竟技场。当Master退出时,则其它所有Slave都必须退出。

Fusion里采用了Reactor模式,每个应用程序可以通过ioctl向reactor注册事件处理器,当有事件发生时,reactor会把事件写入到所注册了的应用程序的fusion文件描述符时,之后应用程序可以从fusion文件描述符里读取到事件数据。

当然,应用程序也可以通过ioctl发送事件给其它应用程序,reactor时会把事件分发给其它应用程序。

下面以触摸屏为例介绍笔点事件的过程:

1.初始化时,driver_open_device创建一个进程,挂在/dev/input/event0上,等待笔点事件。

2.初始化时,应用程序创建另外一个线程,挂在/dev/fusionN(不同的应用程序N值不同)上。

3.当有笔点事件时,通过函数调用dfb_input_dispatch-->fusion_reactor_dispatch->ioctl(FUSION_REACTOR_DISPATCH)把消息丢给内核模块。

4.内核模块中的Reactor把事件数据写入到各个所注册的事件处理器的/dev/fusionN里。

5.应用程序从/dev/fusionN文件中取得事件数据,并调用应用程序内部的reactor处理函数,一般是IDirectFBEventBuffer_InputReact/IDirectFBEventBuffer_WindowReact两个函数。

6.然后,在IDirectFBEventBuffer_InputReact/IDirectFBEventBuffer_WindowReact两个函数中,调用IDirectFBEventBuffer_AddItem把事件加入到窗口的事件队列中。

7.在应用程序的主线程中,就可以通过调用窗口的GetEvent函数从事件队列中获取事件了,最后,把获取的事件分发到各个窗口事件处理函数中。

参考

1.http://www.directfb.com.cn/viewthread.php?tid=6

基于fusion的DirectFB消息流

转载时请注明出处和作者联系方式

作者联系方式:李先静 <xianjimli at hotmail dot com>

2. linux-fusion-8.2.0自带文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: