假设A是当前线程,A发送消息给B,然后从C接收消息
(下面指的应该是异步的吧)
send()
在send-onlyIPC, A发送给B,只有当B的优先级比A高的时候,才会发送给B
receive()
线程A执行receive-onlyIPC,直接切换到C
call()
客户端A执行call IPC,直接切换到B。
replaywait()
服务端A应答客户B,同时等待用户C的下一次要求,只有当B的优先级比C的高的时候,才会转移到B,完成接收动作。
时间片donation
理论上讲,L4线程能够将自己的剩余时间片donate给另外一个线程。如果接受donate的线程没有被阻塞,它将执行完donate的时间片,然后再按照标准调度策略进行调度。
donate分为显式和隐式
显式指的是在thread_switch的时候指定
隐式指的是在IPC路径中,将控制权转移给另外的准备好接收的线程的时候。
上表中总结了时间片donate在L4中的场景。
实际上,L4ka和L4-embedded都不会执行到donate时间片结束,而是最少执行到下次时钟中断,最多执行到自己的时间片结束。
在实时系统中,中断有两个角色,
第一,当被定时器触发,用来标识逝去的时间以及确定时间相关的操作的始终。
第二,当被外设或者传感器触发,用来通知cpu异步事件的发生,此时一般需要立即执行。否则影响实时性。
L4处理中断的过程
主要包括三个函数irq_thread(),handle_interrupt(), 以及控制IC的底层线程。
当L4接收到中断,平台相关的处理函数将会禁止该中断,然后调用handle_interrupt(),该函数产生IPC.
如果用户处理线程没有处于等待状态,将当前的IPC放入到处理线程等待队列中,将irq_thread()设置为运行状态,然后返回到被中断的线程中;
如果用户处理线程处于等待状态,并且被中断线程为irq_thread()或者空线程,直接跳转到对应的线程当中。
最后,如果用户处理线程处理为等待线程,但是被中断线程不是上述的两者,当用户处理线程优先级更高的时候,将会执行直接进程切换(direct process switch),否则将用户处理线程放到就绪队列上,切换回被中断调度,类似于IPC的send()。
irq_thread(),为简单的无限循环执行两个动作,发送挂起消息到处于就绪状态用户处理函数,然后阻塞以等待用户处理函数处理中断时候的回复,当接收到回复的时候,irq_thread()将IC中的该中断号再次使能,将自己挂起。
当前L4ka的不足,中断延迟和内核不可抢占
在之前的设计中,unmap操作耗费的时间比较长,影响了调度性能。在L4-embedded中开始引入了抢占点,并且将部分内存工作继续移动到内核外面。