qemu-RCU锁

RCU (Read-Copy-Update) for synchronization

qemu进程启动后,有一个rcu的线程,用来提供读写锁的

gdb) bt   //rcu线程,用来提供读写锁的
#0  0x00007f40799131c9 in syscall () at /lib64/libc.so.6
#1  0x000055f58a9e23dd in qemu_futex_wait (f=0x55f58b3cb174 <rcu_call_ready_event>, val=4294967295) at /home/work/qemu/include/qemu/futex.h:29
#2  0x000055f58a9e25a6 in qemu_event_wait (ev=0x55f58b3cb174 <rcu_call_ready_event>) at util/qemu-thread-posix.c:460
#3  0x000055f58a9ed023 in call_rcu_thread (opaque=0x0) at util/rcu.c:258
#4  0x000055f58a9e2753 in qemu_thread_start (args=0x55f58bb04b30) at util/qemu-thread-posix.c:521
#5  0x00007f4079befdd5 in start_thread () at /lib64/libpthread.so.0
#6  0x00007f4079918ead in clone () at /lib64/libc.so.6

RCU线程函数

static void *call_rcu_thread(void *opaque)
{
    struct rcu_head *node;

    rcu_register_thread();

    for (;;) {
        int tries = 0;
        int n = atomic_read(&rcu_call_count);

        /* Heuristically wait for a decent number of callbacks to pile up.
         * Fetch rcu_call_count now, we only must process elements that were
         * added before synchronize_rcu() starts.
         */
        while (n == 0 || (n < RCU_CALL_MIN_SIZE && ++tries <= 5)) {
            g_usleep(10000);
            if (n == 0) {
                qemu_event_reset(&rcu_call_ready_event);
                n = atomic_read(&rcu_call_count);
                if (n == 0) {
#if defined(CONFIG_MALLOC_TRIM)
                    malloc_trim(4 * 1024 * 1024);
#endif
                    qemu_event_wait(&rcu_call_ready_event);
                }
            }
            n = atomic_read(&rcu_call_count);
        }

        atomic_sub(&rcu_call_count, n);
        synchronize_rcu();
        qemu_mutex_lock_iothread();
        while (n > 0) {
            node = try_dequeue();
            while (!node) {
                qemu_mutex_unlock_iothread();
                qemu_event_reset(&rcu_call_ready_event);
                node = try_dequeue();
                if (!node) {
                    qemu_event_wait(&rcu_call_ready_event);
                    node = try_dequeue();
                }
                qemu_mutex_lock_iothread();
            }

            n--;
            node->func(node);
        }
        qemu_mutex_unlock_iothread();
    }
    abort();
}

-------------------------------------------------------------------------------------
应用场景:
 例如有链表list1,里面有三个节点 1 2 3,现在有三个用户A B C 都在使用这个链表list1,A现在要删除节点2,按照常规做法是把list1锁住,阻塞用户B C的使用或者阻塞用户A删除节点2,删除节点2,然后用户B C去重新获取链表,这样的缺点很明显达不到高并发的需求,BC被阻塞了,引入了RCU后,先用rcu修饰链表list1,分为新旧链表,用户删除节点2后生成的链表为新链表list11,此时用户BC不受影响,只是将它们使用的链表list1标识为旧链表list01,等到BC不在操作节点2的时候在去释放节点2
 这样的好处:用户A对链表的操作没有阻塞用户B C,而只是标识它们使用的是旧链表,等到它们自身不再使用节点2的时候再去释放,达到了高并发的效果
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值