当前位置: 首页 > 工具软件 > seL4 > 使用案例 >

sel4源码解析(五) - Notification

穆单鹗
2023-12-01

Sel4的通知机制类似于记录型信号量。比如:进程1在等待通知,但进程2还未发送该通知,则会导致进程1暂时被挂载在该notification队列上。一旦进程2发送该通知,则将进程1从该notification队列上取出,并重新加入调度队列。

利用sel4的通知机制可以实现进程之间的同步。下面主要介绍了notification结构体、notification cap的结构体、内核函数和用户程序API。

notification结构体

notification结构体主要包括四个部分:

  • 指向绑定的TCB的指针;
  • 标识符,这里是badge;
  • notification队列头指针(指向的是tcb结构体,其链表指针是tcbEPPrev和tcbEPNext);
  • notification队列尾指针。

结构体如下所示:

block notification {
    padding 16
    field_high ntfnBoundTCB 48 
    field ntfnMsgIdentifier 64
    padding 16
    field_high ntfnQueue_head 48
    field_high ntfnQueue_tail 48
    padding 14
    field state 2
}

notification的三种状态:

enum notification_state {
    NtfnState_Idle    = 0,
    NtfnState_Waiting = 1,
    NtfnState_Active  = 2
};

notification cap结构体

notification cap结构体主要包括了四个部分:

  • badge标识符;
  • 能否接收通知;
  • 能否发送通知;
  • 指向notification结构体的指针。

具体如下所示:

block notification_cap {
    field capNtfnBadge 64	
    field capType 5
    field capNtfnCanReceive 1
    field capNtfnCanSend 1
    padding 9
    field_high capNtfnPtr 48
}

内核函数

void bindNotification(tcb_t *tcb, notification_t *ntfnPtr)
将notification绑定到指定的tcb,该函数:

  1. 将ntfnPtr赋值tcb结构体的成员:tcbBoundNotification
  2. 将tcb赋值notification结构体的成员:ntfnBoundTCB

void unbindNotification(tcb_t *tcb)
notification和tcb取消绑定,该函数:

  1. 清零tcb结构体的成员:tcbBoundNotification
  2. 清零notification结构体的成员:ntfnBoundTCB

void sendSignal(notification_t *ntfnPtr, word_t badge)
给notification发送通知,该函数根据当前notification所处的状态做不同的处理:

  1. 当notification处于NtfnState_Idle时,说明当前notification队列没有等待通知的进程,故该通知无法发送给某个进程。但是,如果该notification同某个进程绑定并且该进程处于ThreadState_BlockedOnReceive状态时,则将该通知发送给该进程;
  2. 当notification处于NtfnState_Waiting时,说明当前notification队列由进程在等待通知。则从notification队列取出第一个进程,置进程状态为就绪态,发起调度;

void receiveSignal(tcb_t *thread, cap_t cap, bool_t isBlocking)
notification等待通知,该函数根据当前notification所处的状态做不同的处理:

  1. 当notification处于NtfnState_Idle和NtfnState_Waiting时,说明当前notification队列为空或者有进程在等待通知,但是没有通知到达。则将当前进程加入notification队列,等待其他的进程发送通知后再唤醒;

用户程序API

void seL4_Signal(seL4_CPtr dest)
进程向notification发送通知。

seL4_MessageInfo_t seL4_Wait(seL4_CPtr src, seL4_Word *sender)
进程等待notification的通知,进程进入阻塞态直到被唤醒。

seL4_MessageInfo_t seL4_Poll(seL4_CPtr src, seL4_Word *sender)
进程等待notification的通知,但是进程不进入阻塞态。

 类似资料: