线程相关

内核实现--线程相关

与线程相关的主要是三个系统调用,下面来论述这三个系统调用的实现逻辑.

#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_WAKEFUTEX_WAKE_BITSET,我们需要执行wake的相关操作.唤醒因uaddr而睡眠的线程.

  • 对于FUTEX_WAITFUTEX_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 updated