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
|
|
@ -115,12 +115,12 @@ sys_rt_sigaction(void)
|
|||
|
||||
struct proc *p = myproc();
|
||||
if (oldactp) {
|
||||
put_user(p->sig_handler[sig], oldactp + SA_HANDLER_OFF);
|
||||
put_user(p->sig_restorer[sig], oldactp + SA_RESTORER_OFF(p));
|
||||
put_user(p->sighand->handler[sig], oldactp + SA_HANDLER_OFF);
|
||||
put_user(p->sighand->restorer[sig], oldactp + SA_RESTORER_OFF(p));
|
||||
if (p->syscall_map) {
|
||||
put_user(p->sig_flags[sig], oldactp + SA_FLAGS_OFF(p));
|
||||
put_user(p->sighand->flags[sig], oldactp + SA_FLAGS_OFF(p));
|
||||
} else {
|
||||
uint32 fl = (uint32)p->sig_flags[sig];
|
||||
uint32 fl = (uint32)p->sighand->flags[sig];
|
||||
put_user(fl, oldactp + SA_FLAGS_OFF(p));
|
||||
}
|
||||
}
|
||||
|
|
@ -134,9 +134,9 @@ sys_rt_sigaction(void)
|
|||
// SIGKILL and SIGSTOP cannot be caught or ignored.
|
||||
if (sig == SIGKILL || sig == SIGSTOP)
|
||||
return -EINVAL;
|
||||
p->sig_handler[sig] = h;
|
||||
p->sig_restorer[sig] = r;
|
||||
p->sig_flags[sig] = fl;
|
||||
p->sighand->handler[sig] = h;
|
||||
p->sighand->restorer[sig] = r;
|
||||
p->sighand->flags[sig] = fl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -218,16 +218,16 @@ deliver_signals(struct trapframe *tf)
|
|||
// SIGSTOP cannot be caught or ignored; the other three stop only by
|
||||
// default. Stopped here and resumed here, by SIGCONT or SIGKILL.
|
||||
if (sig == SIGSTOP ||
|
||||
(sig_default_stops(sig) && myproc()->sig_handler[sig] == 0)) {
|
||||
(sig_default_stops(sig) && myproc()->sighand->handler[sig] == 0)) {
|
||||
myproc()->pending_signals &= ~(1ULL << sig);
|
||||
proc_stop(sig);
|
||||
if (myproc()->killed)
|
||||
exit(W_EXITCODE(0, myproc()->killsig ? myproc()->killsig : SIGKILL));
|
||||
continue;
|
||||
}
|
||||
if (myproc()->sig_handler[sig] <= 1) {
|
||||
if (myproc()->sighand->handler[sig] <= 1) {
|
||||
myproc()->pending_signals &= ~(1ULL << sig);
|
||||
if (myproc()->sig_handler[sig] == 0 && sig_default_kills(sig)) {
|
||||
if (myproc()->sighand->handler[sig] == 0 && sig_default_kills(sig)) {
|
||||
myproc()->killed = 1;
|
||||
if (myproc()->killsig == 0)
|
||||
myproc()->killsig = sig;
|
||||
|
|
@ -283,8 +283,8 @@ deliver_signals(struct trapframe *tf)
|
|||
// shifted rsp, and its ret fell into the sigreturn trampoline,
|
||||
// silently undoing everything. exec() handles this same quirk by
|
||||
// setting tf->rcx = elf.entry.
|
||||
tf->rip = myproc()->sig_handler[sig];
|
||||
tf->rcx = myproc()->sig_handler[sig];
|
||||
tf->rip = myproc()->sighand->handler[sig];
|
||||
tf->rcx = myproc()->sighand->handler[sig];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -344,7 +344,7 @@ addr_t sys_rt_sigsuspend(void)
|
|||
uint64 deliverable = myproc()->pending_signals & ~myproc()->signal_mask;
|
||||
int will_deliver = 0;
|
||||
for (int sig = 1; sig < 32; sig++)
|
||||
if ((deliverable & (1ULL << sig)) && myproc()->sig_handler[sig])
|
||||
if ((deliverable & (1ULL << sig)) && myproc()->sighand->handler[sig])
|
||||
{ will_deliver = 1; break; }
|
||||
|
||||
if (will_deliver && !myproc()->in_signal) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue