futex的pi-support,也就是为futex添加pi算法解决优先级逆转的能力,使用pi-support的futex又称为pi-futex。在linux内核的同步机制中,有一个pi算法的成例,就是rt_mutex实时锁。而futex的pi-support部分就是委托(代理)给rt_mutex进行实现的。

rtmutex,请参看前面的《linux 内核的rt_mutex (realtime互斥体)》。

non-pi futex,请参看前面的《linux 内核的futex》和《linux 内核的各种futex》。

为了让futex使用rt_mutex进行委托,futex设计中添加了一个futex_pi_state结构,这个结构组合了一个rt_mutex作为委托。并将futex_queue这个排队的entry结构添加对futex_pi_state和rt_mutex_waiter的关联,将futex的排队委托成rt_mutex的排队等待rt_mutex_waiter。同时 task_struct 也添加了pi_state_list链表,以维护确保进程(或线程)在持有pi-futex使用的rtmutex代理时退出,进行恢复。

图的上方为pi-futex添加的结构体,下方为non-pi futex使用的结构体。

pi-futex使用了robust-futex定义的锁规则,内核要求用户空间使用它所理解的锁规则,这样一来就可以将原本non-pi futex在用户空间进行的锁操作也委托给内核完成。所以在pi-support的futex系统调用操作 futex_lock_pi 以及 futex_unlock_pi ,还有pi-futex使用在requeue-pi中的futex系统调用操作 futex_wait_requeue_pi 都会在内核在修改用户空间的futex,完成锁操作。

正如这些操作的函数名称字面一样,futex_lock_pi 执行上锁操作(lock)和提供pi-support的排队(pi),而 futex_wait 只单单提供排队服务(wait)。futex_unlock_pi 执行解锁操作(unlock)和提供pi-support的排队唤醒(pi),而 futex_wake 只单单提供排队的唤醒(wake)。

当用户空间使用 futex_lock_pi 进行上锁的slowpath的场合中,内核从排队中唤醒后会尝试对pi-futex进行上锁(锁状态修改),失败后会再次到rt_mutex代理上排队等待。当内核对pi-futex上锁成功后就会返回用户空间,这时用户空间已经得到了内核上好的锁。

这里必须要注意,futex_lock_pi 和 futex_unlock_pi 都是临界区代码,必须被同步。释放pi-futex上的锁不能够像non-pi futex那样在用户空间任意自由地解锁,必须委托rt_mutex锁。由于pi-futex委托了rt_mutex,因此对pi-futex的trylock也不能non-pi futex那样简单地判断失败然后返回,必须进行rt_mutex的trylock委托,所以pi-futex的trylock在失败时,其开销比较大。

futex_lock_pi 和 futex_unlock_pi 在临界区同步使用的是futex_hash_bucket的保护锁,futex模块的共享等待队列。futex_lock_pi 只有在对rt_mutex进行委托调用(rt_mutex_timed_futex_lockrt_mutex_trylock)时才会离开临界区,之后又重新回到临界区。虽然pi-futex排队在rt_mutex锁上,但是它的lock和unlock临界区却使用futex模块的共享等待队列的保护锁同步,也就是说,它与跟它共享相同的共享等待队列的futex,都同步地进行futex系统调用。

下面临界区图示

为什么pi-futex在rt_mutex锁上面委托了排队,还要在futex_hash_bucket->chain上入队呢?futex_queue代表着一个futex的waiter,而futex系统调用并不使用额外的映射表维护pi-futex与rt_mutex委托锁的对应关系,而是将同一个pi-futex的所有futex_queue(等待entry)关联到rt_mutex委托锁上,就可以通过futex_key在futex_hash_bucket->chain上找出futex_queue,从而得到这个pi-futex委托的rt_mutex锁。对于futex系统调用来说,它可见的futex等待就是futex_hash_bucket以及入队其中的futex_queue。从futex_hash_bucket搜索出的第一个futex_queue,已经不能看作是第一个唤醒的等待了,必须委托给它关联的rt_mutex进行仲裁。futex_queue除了多对一关联到rt_mutex外,还一对一关联到rt_mutex_waiter。这时wake_futex_pi不是依据futex_queue来唤醒任务,而使用委托的rt_mutex锁的等待队列waiters上的rt_mutex_waiter来唤醒任务。当pi-futex的阻塞任务唤醒后,才会将自己的futex_queue移出futex_hash_bucket。所以可以看到futex_lock_pi在委托rt_mutex进行排队的前后,也生成了一个futex_queue进行futex_hash_bucket的入队和出队。

linux 内核的futex pi-support,即pi-futex使用rt_mutex委托的更多相关文章

  1. linux 内核的futex

    futex是linux内核为用户空间实现锁等同步机制而设计的同步排队(队列queueing)服务.在futex.c的注释中,futex起源于"Fast Userspace Mutex&quo ...

  2. linux 内核的各种futex

    futex 设计成用户空间快速锁操作,由用户空间实现fastpath,以及内核提供锁竞争排队仲裁服务,由用户空间使用futex系统调用来实现slowpath.futex系统调用提供了三种配对的调用接口 ...

  3. How To Install Linux & Nginx & MySQL & PHP (LEMP) stack on Raspberry Pi 3,Raspberry Pi 3,LEMP,Nginx,PHP, LEMP (not LNMP)

    1.   How To Install Linux & Nginx & MySQL & PHP (LEMP) stack on Raspberry Pi 3         R ...

  4. linux内核级同步机制--futex

    在面试中关于多线程同步,你必须要思考的问题 一文中,我们知道glibc的pthread_cond_timedwait底层是用linux futex机制实现的. 理想的同步机制应该是没有锁冲突时在用户态 ...

  5. linux内核数据结构学习总结

    目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...

  6. [中英对照]Linux kernel coding style | Linux内核编码风格

    Linux kernel coding style | Linux内核编码风格 This is a short document describing the preferred coding sty ...

  7. Linux内核编程规范与代码风格

    source: https://www.kernel.org/doc/html/latest/process/coding-style.html translated by trav, travmym ...

  8. 嵌入式Linux内核+根文件系统构建工具-Buildroot 快速入手指导【转】

    本文转载自:https://my.oschina.net/freeblues/blog/596448 嵌入式Linux内核+根文件系统构建工具-Buildroot 快速入手指导 buildroot 是 ...

  9. C 语言代码风格之 Linux 内核代码风格

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区:https://bbs.huaweicloud.com/b ...

随机推荐

  1. 基于ELK的数据分析实践——满满的干货送给你

    很多人刚刚接触ELK都不知道如何使用它们来做分析,经常会碰到下面的问题: 安装完ELK不知从哪下手 拿到数据样本不知道怎么分解数据 导入到elasticsearch中奇怪为什么搜不出来 搜到结果后,不 ...

  2. Java虚拟机工作原理

    Java虚拟机工作原理 首先我想从宏观上介绍一下Java虚拟机的工作原理.从最初的我们编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编译器(javac ...

  3. 设置int、float型数据的输出格式

    设置整型输出的有效位数,比如在输出时间时时.分.秒都是两位有效数字,如果是5分钟应该输出00:05:00.需要加上头文件<iomanip> cout<<setw(2)<& ...

  4. Jenkis Editable Email Notification Plugin 使用介绍

    Jenkis Editable Email Notification Plugin 使用介绍 前言 Jenkins本身提供的Email插件功能实在有限,只能提供当前Job的基本信息,比如成功.失败以及 ...

  5. 【笔记】归纳js getcomputedStyle, currentStyle 以及其相关用法

      好吧,鉴于前端则个行业知识宽度广而深,早期看过高程介绍过的获取元素计算后的最终样式(浏览器显示的最终样式)的方法现在也忘得七七八八了 于是百度了一下,看了一下大神张鑫旭的博客,这里写个随笔记录一下 ...

  6. Oracle ASM数据库故障数据恢复过程

    一.故障描述 ASM磁盘组掉线 ,ASM实例不能mount.ASM磁盘组有4个500G的磁盘组成,数据库和ASM软件为10.2.0.1,急需恢复oracle数据库.二.故障分析   分析组成ASM磁盘 ...

  7. 测试开发Python培训:自动发布新浪微博-技术篇

    测试开发Python培训:自动发布新浪微博-技术篇   在前面我们教大家如何登陆,大家需要先看自动登陆新浪微博(http://www.cnblogs.com/laoli0201/articles/48 ...

  8. CSS3选择器~一看吓一跳,这么多不会

    复习CSS时发现很多选择器不会,因为平时很少用到.现在干脆一不做二不修,全部温习一遍.本文参考http://css.doyoe.com/. 一.元素选择器 图片来自:http://css.doyoe. ...

  9. es suggest did you mean资料

    term suggester 功能介绍 term suggester 根据提供的文档提供搜索关键词的建议,也就是关键词自动纠错.该链接介绍如何使用 term suggester 语法.term sug ...

  10. yii2-验证规则,rules,判断条件

    yii2模型的验证规则,简单的使用我就不详细说了,想看的可以去看官网教程http://www.yiichina.com/doc/guide/2.0/structure-models#validatio ...