和down_read不一样,down_read_trylock只是尝试获取读锁,如果成功,那么自然是好的,直接返回1,如果失败,也不会阻塞,只是返回0就可以了。代码主逻辑在__down_read_trylock函数中,如下: tmp的初始值设定为RWSEM_UNLOCKED_VALUE(0值),因此第一次循环是为当前是空锁而做的优化:如果当前的sem->count等于0,那么给sem...
2.reader持锁情况下,另外的reader再来持锁时,也不会成功 3.rwsem_down_read_slowpath 时,如果wait list空的,且是writer持锁或者设置了handoff则不能获得锁(正常是可以的,因为是读者持锁) 4.rwsem_try_write_lock 时,可以直接返回 设置RWSEM_FLAG_HANDOFF的地方 1.在rwsem_down_write_slowpath 慢速路径被唤醒后...
rwsem_down_read_slowpath会使用这个新值作为参数。 当reader的数量过多(以至于都溢出了)的时候,需要禁止乐观自旋。 这里是持锁成功的路径。RWSEM_READ_FAILED_MASK上一节已经解释,这里不再赘述。这里需要注意的是rwsem_set_reader_owned函数中flag的设定,由于reader进入临界区,因此RWSEM_READER_OWNED也需要设定。RWSEM...
down_read()和down_write()函数分别用来请求读信号量和写信号量。同理,up_read()和up_write()函数分别用来释放读信号量和写信号量。down_read_trylock()和down_write_trylock()函数分别与down_read()和down_write()函数类似,只是当信号量忙的时候不会阻塞进程。最后,还有一个重要的函数,downgrade_write(),用...
voiddown_read(struct rw_semaphore*sem);intdown_read_trylock(struct rw_semaphore*sem);voidup_read(struct rw_semaphore*sem); 对down_read 的调用提供了对受保护资源的只读访问,可和其他读取者并发地访问。注意down_read可能会将调用进程置于不可中断的休眠。down_read_trylock 不会在读取访问不可获得时等待...
* we can bug out early if this is from code which shouldn't.*/if(!down_read_trylock(&mm->mmap_sem)) {if(!user_mode(regs) && !search_exception_tables(regs->ARM_pc))---发生在内核空间,且没有在exception tables查询到该地址,跳转到no_context。gotono_context; retry: down...
函数调用时被调用函数会在自己的栈帧中保存即将被修改到的寄存器,所以我们可以在down_read()及它之后的函数调用中找到这两个寄存器: 也就是说下面几个函数中,只要找到用到x21或x28,必然会在它的栈帧中保存这些寄存器。 先从最底部的down_read()开始找: ...
__down_read & __up_read 根据count字段的含义,count + 1小于0说明原本存在写者或者等待队列非空,因此不能获得锁,rwsem_down_read_failed调用 一个读者释放后count - 1小于-1说明等待队列非空,因此还需唤醒等待的写者 Rwsem_down_read不能直接获取时调用,首先判断等待队列是否为空,为空则字段置为非空,并将...
先从最底部的down_read()开始找: 显然它没有用到x21或x28,继续看rwsem_down_read_failed()的汇编代码: 在这个函数中找到x21,它保存在rwsem_down_read_failed栈帧的偏移32字节的位置。 rwsem_down_read_failed()的sp是0xffffffd6d9e4bcb0 sp + 32 =0xffffffd6d9e4bcd0,用rd命令查看地址0xffffffd6...
(sizeof(struct uts_namespace), GFP_KERNEL); if (!ns) return ERR_PTR(-ENOMEM); // 信号量-1,临界区 down_read(&uts_sem); // 拷贝符进程uts_namespace memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); // 信号量+1 up_read(&uts_sem); kref_init(&ns->kref); return ns;...