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
|
|
@ -711,9 +711,21 @@ consoleread(struct inode *ip, uint64 off, char *dst, int n)
|
|||
|
||||
iunlock(ip);
|
||||
target = n;
|
||||
uint t0 = ticks;
|
||||
acquire(&input_lock);
|
||||
while(n > 0){
|
||||
while(v->in.r == v->in.w){
|
||||
// Raw mode with VMIN 0 is a poll: VTIME tenths of a second at most, and
|
||||
// none at all when that is 0 too. It waited for a key regardless, and
|
||||
// btop -- which drains its input with exactly such reads -- hung on the
|
||||
// read after the last key, so `q` never quit it.
|
||||
if (!(v->tio.c_lflag & ICANON) && v->tio.c_cc[VMIN] == 0 &&
|
||||
(target - n > 0 ||
|
||||
(uint)(ticks - t0) >= (uint)v->tio.c_cc[VTIME] * (HZ / 10))) {
|
||||
release(&input_lock);
|
||||
ilock(ip);
|
||||
return target - n;
|
||||
}
|
||||
if (v->in.eof) {
|
||||
v->in.eof = 0;
|
||||
release(&input_lock);
|
||||
|
|
@ -752,7 +764,11 @@ consoleread(struct inode *ip, uint64 off, char *dst, int n)
|
|||
acquire(&input_lock);
|
||||
continue;
|
||||
}
|
||||
sleep(&v->in.r, &input_lock);
|
||||
// A VTIME wait has to see the clock move as well as a key arrive.
|
||||
if (!(v->tio.c_lflag & ICANON) && v->tio.c_cc[VMIN] == 0)
|
||||
sleep(&ticks, &input_lock);
|
||||
else
|
||||
sleep(&v->in.r, &input_lock);
|
||||
}
|
||||
c = v->in.buf[v->in.r++ % VT_INPUT_BUF];
|
||||
*dst++ = c;
|
||||
|
|
|
|||
Loading…
Reference in a new issue