x
x
xv6-sifive文档
Search…
⌃K

线程相关

内核实现--线程相关

与线程相关的主要是三个系统调用,下面来论述这三个系统调用的实现逻辑.
#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.