Threads
A thread is a struct proc that shares three counted objects with others of its group: the address space (struct mm: page tables, heap top, VMAs and a lock for changing them), the descriptor table, and the signal dispositions. clone() shares what its flags say and fork() copies. - clone(): pthread_create's shape (VM, FILES, SIGHAND, THREAD, SETTLS, PARENT_SETTID, CHILD_CLEARTID) and posix_spawn's (VM, VFORK, a stack). - futex: WAIT, WAIT_BITSET with timeouts, WAKE, REQUEUE, CMP_REQUEUE, keyed by the word's kernel address so shared pages meet. set_tid_address keeps the word that exit zeroes and wakes, for pthread_join. - exit ends a thread; exit_group, a fatal signal, or the leader exiting ends them all. reapd frees exited threads; the leader is reaped by its parent once the rest are gone. getpid is the group, gettid the thread. - Stops and resumes reach every thread; other process signals the leader. - exec kills the other threads and unshares the dispositions. - No TLB shootdown, so pages unmapped from a shared address space are freed only once every CPU has reloaded CR3 or is idle. - procfs: /proc lists processes, task/ lists threads, comm, Threads:, Tgid. - The console honours VMIN 0 / VTIME (btop's input drain hung on it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
2372806862
commit
f4d7f9100d
19 changed files with 1300 additions and 248 deletions
|
|
@ -123,7 +123,7 @@ sock_to_fd(struct socket *s, int sflags)
|
|||
f->off = 0;
|
||||
f->nonblock = (sflags & SOCK_NONBLOCK) != 0;
|
||||
if (sflags & SOCK_CLOEXEC)
|
||||
myproc()->ofile_flags[fd] |= FD_CLOEXEC;
|
||||
myproc()->files->flags[fd] |= FD_CLOEXEC;
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ argsock(int n, struct socket **ps)
|
|||
|
||||
if (argint(n, &fd) < 0)
|
||||
return -EBADF;
|
||||
if (fd < 0 || fd >= NOFILE || !(f = myproc()->ofile[fd]))
|
||||
if (fd < 0 || fd >= NOFILE || !(f = myproc()->files->ofile[fd]))
|
||||
return -EBADF;
|
||||
if (f->type != FD_SOCKET)
|
||||
return -ENOTSOCK;
|
||||
|
|
@ -471,7 +471,7 @@ SYSCALL_DEFINE(socketpair)
|
|||
return fd0;
|
||||
}
|
||||
if ((fd1 = sock_to_fd(b, sflags)) < 0) {
|
||||
myproc()->ofile[fd0] = 0;
|
||||
myproc()->files->ofile[fd0] = 0;
|
||||
sockclose(a);
|
||||
sockclose(b);
|
||||
return fd1;
|
||||
|
|
@ -479,8 +479,8 @@ SYSCALL_DEFINE(socketpair)
|
|||
|
||||
int sv[2] = { fd0, fd1 };
|
||||
if (copy_to_user(usv, sv, sizeof(sv)) < 0) {
|
||||
myproc()->ofile[fd0] = 0;
|
||||
myproc()->ofile[fd1] = 0;
|
||||
myproc()->files->ofile[fd0] = 0;
|
||||
myproc()->files->ofile[fd1] = 0;
|
||||
sockclose(a);
|
||||
sockclose(b);
|
||||
return -EFAULT;
|
||||
|
|
@ -808,7 +808,7 @@ argsockfile(int n, struct socket **ps, struct file **pf)
|
|||
|
||||
if (argint(n, &fd) < 0)
|
||||
return -EBADF;
|
||||
if (fd < 0 || fd >= NOFILE || !(f = myproc()->ofile[fd]))
|
||||
if (fd < 0 || fd >= NOFILE || !(f = myproc()->files->ofile[fd]))
|
||||
return -EBADF;
|
||||
if (f->type != FD_SOCKET)
|
||||
return -ENOTSOCK;
|
||||
|
|
@ -879,7 +879,7 @@ scm_gather(struct msghdr *m, struct file **fs, int *nfp)
|
|||
r = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (ufd < 0 || ufd >= NOFILE || !(f = myproc()->ofile[ufd])) {
|
||||
if (ufd < 0 || ufd >= NOFILE || !(f = myproc()->files->ofile[ufd])) {
|
||||
r = -EBADF;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1078,7 +1078,7 @@ SYSCALL_DEFINE(recvmsg)
|
|||
if (d < 0)
|
||||
break;
|
||||
if (flags & MSG_CMSG_CLOEXEC)
|
||||
myproc()->ofile_flags[d] |= FD_CLOEXEC;
|
||||
myproc()->files->flags[d] |= FD_CLOEXEC;
|
||||
ufd[installed++] = d;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue