线程相关
与线程相关的主要是三个系统调用,下面来论述这三个系统调用的实现逻辑.
#define SYS_futex 98
#define SYS_set_tid_address 96
#define SYS_clone 220
futex
函数原型:
__syscall (SYS_
futex, int *uaddr, int op, int val, const struct timespec *timeout,int *uaddr2, int val3);
- uaddr:futex变量的地址.
- op:futex执行的操作.
- val:传来的参数
对于不同的futex操作,我们有不同的处理方法:
- 首先判断是否为共享锁.
- 对于
FUTEX_LOCK_PI
,FUTEX_UNLOCK_PI
,FUTEX_TRYLOCK_PI
,FUTEX_WAIT_REQUEUE_PI
,FUTEX_CMP_REQUEUE_PI
.我们不需要做任何操作. - 对于
FUTEX_WAKE
和FUTEX_WAKE_BITSET
,我们需要执行wake的相关操作.唤醒因uaddr而睡眠的线程. - 对于
FUTEX_WAIT
和FUTEX_WAIT_BITSET
,我们需要执行wait相关的操作,睡眠该进程,标记睡眠的原因. - 对于
FUTEX_REQUEUE
,我们需要更换某个线程睡眠的原因.
set-tid-address
函数原型:
__syscall(SYS_set_tid_address, int *tidptr);
- tidptr:一个地址.
这个系统调用将当前线程的clear_child_tid改为tidptr
如果当一个 线程结束的时候其clear_child_tid不为NULL就要执行:
futex(clear_child_tid, FUTEX_WAKE, 1, NULL, NULL, 0);
clone
我们需要对clone函数进行一定程度地更改.将clone函数的函数定义改为:
int clone(uint64 flag, uint64 stack, uint64 ptid, uint64 tls, uint64 ctid)
那么对于不同的flag,我们需要做不同的操作:
- 如果为
CLONE_FILES
,则需要把ofile字段进行深拷贝. - 如果为
CLONE_SIGHAND
,则需要把相关的信号信息进行拷贝. - 如果为
CLONE_CHILD_SETTID
,则需要把set_child_tid字段设置为ctid. - 如果为
CLONE_CHILD_CLEARTID
,则需要把clear_child_tid字段设置为ctid.
Last modified 5mo ago