结构体 | |
struct | FutexNode |
每个futex node对应一个被挂起的task ,key值唯一标识一把用户态锁,具有相同key值的node被queue_list串联起来表示被同一把锁阻塞的task队列。 更多... | |
函数 | |
UINT32 | OsFutexInit (VOID) |
VOID | OsFutexNodeDeleteFromFutexHash (FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags) |
从哈希桶上删除快锁 更多... | |
INT32 | OsFutexWake (const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) |
唤醒一个被指定锁阻塞的线程 更多... | |
INT32 | OsFutexWait (const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime) |
设置线程等待 | 向Futex表中插入代表被阻塞的线程的node 更多... | |
INT32 | OsFutexRequeue (const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr) |
调整指定锁在Futex表中的位置 更多... | |
FUTEX_WAIT 这个操作用来检测有uaddr指向的futex是否包含关心的数值val,如果是,则继续sleep直到FUTEX_WAKE操作触发。 加载futex的操作是原子的。这个加载,从比较关心的数值,到开始sleep,都是原子的,与另外一个对于同一个 futex的操作是线性的,串行的,严格按照顺序来执行的。如果线程开始sleep,就表示有一个waiter在futex上。 如果futex的值不匹配,回调直接返回失败,错误代码是EAGAIN。 与期望值对比的目的是为了防止丢失唤醒的操作。如果另一个线程在基于前面的数值阻塞调用之后,修改了这个值, 另一个线程在数值改变之后,调用FUTEX_WAIT之前执行了FUTEX_WAKE操作,这个调用的线程就会观察到数值变换并且无法唤醒。 这里的意思是,调用FUTEX_WAIT需要做上面的一个操作,就是检测一下这个值是不是我们需要的,如果不是就等待, 如果是就直接运行下去。之所以检测是为了避免丢失唤醒,也就是防止一直等待下去,比如我们在调用FUTEX_WAIT之前, 另一个线程已经调用了FUTEX_WAKE,那么就不会有线程调用FUTEX_WAKE,调用FUTEX_WAIT的线程就永远等不到信号了,也就永远唤醒不了了。 如果timeout不是NULL,就表示指向了一个特定的超时时钟。这个超时间隔使用系统时钟的颗粒度四舍五入, 可以保证触发不会比定时的时间早。默认情况通过CLOCK_MONOTONIC测量,但是从Linux 4.5开始,可以在futex_op中设置 FUTEX_CLOCK_REALTIME使用CLOCK_REALTIME测量。如果timeout是NULL,将会永远阻塞。 注意:对于FUTEX_WAIT,timeout是一个关联的值。与其他的futex设置不同,timeout被认为是一个绝对值。 使用通过FUTEX_BITSET_MATCH_ANY特殊定义的val3传入FUTEX_WAIT_BITSET可以获得附带timeout的FUTEX_WAIT的值。
在文件 los_futex_pri.h 中定义.
UINT32 OsFutexInit | ( | VOID | ) |
在文件 los_futex.c 第 144 行定义.
VOID OsFutexNodeDeleteFromFutexHash | ( | FutexNode * | node, |
BOOL | isDeleteHead, | ||
FutexNode ** | headNode, | ||
BOOL * | queueFlags | ||
) |
从哈希桶上删除快锁
在文件 los_futex.c 第 302 行定义.
INT32 OsFutexRequeue | ( | const UINT32 * | userVaddr, |
UINT32 | flags, | ||
INT32 | wakeNumber, | ||
INT32 | count, | ||
const UINT32 * | newUserVaddr | ||
) |
调整指定锁在Futex表中的位置
在文件 los_futex.c 第 1022 行定义.
设置线程等待 | 向Futex表中插入代表被阻塞的线程的node
在文件 los_futex.c 第 693 行定义.
唤醒一个被指定锁阻塞的线程
在文件 los_futex.c 第 815 行定义.