fusion-linux 簡介–轉載加翻譯

來源:互聯網
上載者:User
今天高興,多發個文章慶祝,呵呵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 API2.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內建文檔

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.