futex内核实现源码分析(2)

相关数据结构

由上一章节可知,futex变量创建于用户空间,在进程或线程间共享,当进程或线程想要进入临界区时,通常会判断futex变量是否满足条件,若满足则成功进入临界区,否则则阻塞在该futex变量上;当进程或线程将要离开临界区时,则会唤醒阻塞在futex变量上的其他进程或线程。在内核中通过struct futex_q结构将一个futex变量与一个挂起的进程(线程)关联起来。

struct futex_q:

struct futex_q {
    struct plist_node list;      //链表节点,链入链表
    struct task_struct *task; //挂起在该futex变量关联的进程(线程)
    spinlock_t *lock_ptr;      //自旋锁,控制链表访问
    union futex_key key;     //futex变量地址标识

       //下面三个与优先级继承相关
    struct futex_pi_state *pi_state;
    struct rt_mutex_waiter *rt_waiter;
    union futex_key *requeue_pi_key;
     
    u32 bitset;     //类似掩码匹配
};

union futex_key:futex变量地址标识

union futex_key {
    struct {
        unsigned long pgoff;
        struct inode *inode;
        int offset;
    } shared;     //不同进程间通过文件共享futex变量,表明该变量在文件中的位置
    struct {
        unsigned long address;
        struct mm_struct *mm;
        int offset;
    } private;  //同一进程的不同线程共享futex变量,表明该变量在进程地址空间中的位置
    struct {
        unsigned long word;
        void *ptr;
        int offset;
    } both;
};

在内核中通过一个哈希表来维护所有挂起阻塞在futex变量上的进程(线程),不同的futex变量会根据其地址标识计算出一个hash key定位到一个哈希桶链上,因此挂起阻塞在同一个futex变量的所有进程(线程)会定位到同一个哈希桶链上。

struct futex_hash_bucket :

struct futex_hash_bucket {
    spinlock_t lock;                 //自旋锁,用于控制chain的访问,struct futex_q 中lock_ptr,就是引用其所在的哈希桶链的自旋锁,方便操作
    struct plist_head chain;     //优先级链,与传统等待队列不同,futex使用优先级链表来实现等待队列,是为了实现优先级继承,从而解决优先级翻转问题
};

futex哈希表:

static struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];

同一进程下不同线程阻塞在futex变量模型:


futex.jpg

内核fuetx初始化,初始化futex哈希表的每一个哈希桶链的头。

linux/kernel/futex.c
static int __init futex_init(void)
{
    int i;

    futex_detect_cmpxchg();

    for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
        plist_head_init(&futex_queues[i].chain);
        spin_lock_init(&futex_queues[i].lock);
    }

    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,172评论 0 23
  • 1 临界区 1.1简介 在早期计算机系统中,只有一个任务进程在执行,并不存在资源的共享与竞争。随着技术和需求的飞速...
    Fly晴天里Fly阅读 9,079评论 2 13
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,731评论 0 11
  • 2017年业已过去23天,23天前新的篇章开启,过去的一年成为历史。这是怎样的一段历史呢,等我认真想想看能否给自己...
    以为在写字阅读 191评论 0 0
  • 已有一个星期没写日记了。人真的是懒惰的。当你的思想不积极的时候,行为就没办法积极。 还好每天还坚持带着孩子读经典。...
    紫彤阅读 207评论 0 3