AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
proc.c
Go to the documentation of this file.
1
11
12
13#include <core/system.h>
14#include <core/panic.h>
15#include <core/string.h>
16#include <core/arch.h>
17
18#include <mm/pmap.h>
19#include <mm/mm.h>
20#include <mm/vm.h>
21
22#include <sys/proc.h>
23#include <sys/sched.h>
24
25#include <fs/vfs.h>
26#include <dev/tty.h>
27
28#include <ds/queue.h>
29#include <ds/bitmap.h>
30
31MALLOC_DEFINE(M_PROC, "proc", "process structure");
32MALLOC_DEFINE(M_SESSION, "session", "session structure");
33MALLOC_DEFINE(M_PGROUP, "pgroup", "process group structure");
34MALLOC_DEFINE(M_FDS, "fds", "file descriptor array");
35
36/* every process */
37struct queue *procs = QUEUE_NEW();
38
39struct proc *initproc;
40
41/* every session (each has its process groups) */
43
44/* the process IDs in use */
46
47/* The last process ID given out. The next one is the first free ID after
48 * it, wrapping around, as UNIX does: the ID of a process just reaped isn't
49 * given out again at once, so a kill() meant for it doesn't find a new
50 * process. */
51static int last_pid;
52
56static int pid_is_group(int pid)
57{
58 queue_for (snode, sessions) {
59 struct session *session = snode->value;
60
61 if (session->sid == pid)
62 return 1;
63
64 queue_for (gnode, session->pgps) {
65 struct pgroup *pgrp = gnode->value;
66
67 if (pgrp->pgid == pid)
68 return 1;
69 }
70 }
71
72 return 0;
73}
74
81{
82 size_t range = pid_bitmap->max_idx - 1; /* 1 to max_idx - 1 */
83
84 for (size_t n = 0; n < range; ++n) {
85 int pid = 1 + (last_pid + n) % range;
86
87 if (!bitmap_check(pid_bitmap, pid) && !pid_is_group(pid)) {
88 bitmap_set(pid_bitmap, pid);
89 last_pid = pid;
90 return pid;
91 }
92 }
93
94 return -1;
95}
96
102void proc_pid_free(int pid)
103{
104 bitmap_clear(pid_bitmap, pid);
105}
106
114int proc_new(struct proc **ref)
115{
116 int err = 0;
117 struct proc *proc = NULL;
118 struct thread *thread = NULL;
119 struct pmap *pmap = NULL;
120
121 proc = kmalloc(sizeof(struct proc), &M_PROC, M_ZERO);
122
123 if (!proc) {
124 err = -ENOMEM;
125 goto error;
126 }
127
128 err = thread_new(proc, &thread);
129
130 if (err != 0)
131 goto error;
132
133 pmap = pmap_create();
134
135 if (pmap == NULL) {
136 err = -ENOMEM;
137 goto error;
138 }
139
141
142 /* every signal has its default action */
143 for (int i = 0; i < SIG_MAX; ++i)
144 proc->sigaction[i].sa_handler = SIG_DFL;
145
146 proc->running = 1;
147
148 if (!enqueue(procs, proc)) {
149 err = -ENOMEM;
150 goto error;
151 }
152
153 if (ref)
154 *ref = proc;
155
156 return 0;
157
158error:
159 if (pmap)
161
162 if (thread) {
163 queue_remove(&proc->threads, thread);
164 kfree(thread);
165 }
166
167 if (proc)
168 kfree(proc);
169
170 return err;
171}
172
180{
181 queue_for (node, procs) {
182 struct proc *proc = node->value;
183 if (proc->pid == pid)
184 return proc;
185 }
186
187 return NULL;
188}
189
197int proc_init(struct proc *proc)
198{
199 if (!proc)
200 return -EINVAL;
201
202 /* no free ID: fork() says to try again */
203 if ((proc->pid = proc_pid_alloc()) < 0)
204 return -EAGAIN;
205
206 proc->fds = kmalloc(FDS_COUNT * sizeof(struct fd), &M_FDS, M_ZERO);
207
208 if (!proc->fds) {
210 return -ENOMEM;
211 }
212
213 return 0;
214}
215
227int pgrp_orphaned(struct pgroup *pgrp, struct proc *gone)
228{
229 queue_for (node, pgrp->procs) {
230 struct proc *p = node->value, *parent = p->parent;
231
232 if (p == gone || p->zombie || !parent || parent == gone || parent == initproc)
233 continue;
234
235 if (parent->pgrp != pgrp && parent->pgrp->session == pgrp->session)
236 return 0;
237 }
238
239 return 1;
240}
241
245static void pgrp_orphaned_hangup(struct pgroup *pgrp, struct proc *gone)
246{
247 int stopped = 0;
248
249 queue_for (node, pgrp->procs) {
250 struct proc *p = node->value;
251
252 if (p != gone && p->running && p->stopped)
253 stopped = 1;
254 }
255
256 if (stopped && pgrp_orphaned(pgrp, gone)) {
257 signal_pgrp_send(pgrp, SIGHUP);
258 signal_pgrp_send(pgrp, SIGCONT);
259 }
260}
261
264static int pgrp_other_same_session(struct proc *p, struct proc *q)
265{
266 return p->pgrp != q->pgrp && p->pgrp->session == q->pgrp->session;
267}
268
272static void proc_zombie_notify(struct proc *proc)
273{
274 struct proc *parent = proc->parent;
275
276 if (!parent) {
278 return;
279 }
280
281 int nowait = parent->sigaction[SIGCHLD].sa_handler == SIG_IGN ||
282 (parent->sigaction[SIGCHLD].sa_flags & SA_NOCLDWAIT);
283
285 signal_proc_send(parent, SIGCHLD);
286
287 if (nowait)
289}
290
305int proc_threads_end(struct proc *proc, struct thread *keep, int exiting)
306{
307 int elsewhere = 0;
308
309 for (struct qnode *node = proc->threads.head, *next; node; node = next) {
310 struct thread *thread = node->value;
311 next = node->next;
312
313 if (thread == keep)
314 continue;
315
317 thread->killed = 1;
319 elsewhere++;
320
321 if (exiting) {
322 queue_node_remove(&proc->threads, node);
323 thread->owner = NULL;
324 }
325
326 continue;
327 }
328
329 queue_node_remove(&proc->threads, node);
330
331 /* take it off the wait queue it sleeps on, or the ready list */
332 list_remove(&thread->run_link);
333 thread->waitq = NULL;
334
336
337 /* it won't return from its system call: let go of the files the
338 * call held */
340
341 /* a zombie thread (thread_exit()) released its resources already */
342 if (thread->state != ZOMBIE)
344
345 kfree(thread);
346 }
347
348 return elsewhere;
349}
350
359{
360 if (!curthread || curthread->owner != proc)
361 return;
362
363 while (proc_threads_end(proc, curthread, 0))
365}
366
375void proc_kill(struct proc *proc)
376{
377 if (proc->pid == 1) {
378 if (proc->exit)
379 panic("init killed");
380
381 printk("kernel: reached target reboot\n");
382 arch_reboot();
383
384 panic("reboot not implemented\n");
385 }
386
387 proc->running = 0;
388
389 /* no more SIGALRM */
390 sched_alarm(proc, 0, 0, NULL, NULL);
391
392 /* its threads end, the current one last (it runs this code) */
393 struct thread *self = curthread && curthread->owner == proc ? curthread : NULL;
394 int kill_curthread = self != NULL;
395
396 proc_threads_end(proc, self, 1);
397
398 if (self) {
399 queue_remove(&proc->threads, self);
401 }
402
403 /* close every descriptor */
404 for (int i = 0; i < FDS_COUNT; ++i)
406
407 /* what follows frees what a thread killing its own process runs on
408 * (its address space, and its process once reaped), so it must not be
409 * switched out until it is gone */
410 if (kill_curthread)
412
413 struct vm_space *vm_space = &proc->vm_space;
416
417 /* nothing may switch to the freed page tables */
419
420 /* the descriptor table and the working directory */
421 kfree(proc->fds);
422
423 if (proc->cwd)
425
426 proc->cwd = NULL;
427
428 proc->sig_pending = 0;
429
430 /* its own group: its parent, in another group of the session, may
431 * have been what kept the group from being orphaned */
434
435 /* its children become init's: init waits for them (for the zombies
436 * among them now, for the others when they end). A child's group, if
437 * it is another group of the session, may be orphaned now */
438 struct qnode *node = procs->head;
439 while (node) {
440 struct proc *_proc = node->value;
441 node = node->next; /* proc_reap() removes the current node */
442
443 if (_proc->parent == proc) {
444 _proc->parent = initproc;
445
446 if (pgrp_other_same_session(_proc, proc))
448
449 if (_proc->zombie)
450 proc_zombie_notify(_proc);
451 }
452 }
453
454 /* if it leads its session, the session ends and its controlling
455 * terminal hangs up (a zombie stays in its process group until it is
456 * reaped: waitpid() matches it by group) */
457 struct session *session = proc->pgrp->session;
458
459 if (session->leader == proc) {
460 if (session->ctty)
462
464 }
465
466 proc->zombie = 1;
467
468 /* tell its parent, which may wait for it */
470
471 if (kill_curthread) {
473 panic("How did we get here?");
474 }
475}
476
484int proc_reap(struct proc *proc)
485{
486 /* its CPU times count as the parent's children's */
487 if (proc->parent) {
490 }
491
493
494 queue_node_remove(proc->pgrp->procs, proc->pgrp_node);
496
497 /* the name stayed with the zombie until now (ps and /proc show it) */
498 kfree(proc->name);
499
500 queue_remove(procs, proc);
501 kfree(proc);
502
503 return 0;
504}
505
515{
516 for (int i = 0; i < FDS_COUNT; ++i) {
517 if (!proc->fds[i].file) {
518 proc->fds[i] = (struct fd) {.file = FD_RESERVED};
519 return i;
520 }
521 }
522
523 return -1;
524}
525
532void proc_fd_release(struct proc *proc, int fd)
533{
534 if (fd >= 0 && fd < FDS_COUNT)
535 proc->fds[fd] = (struct fd) {0};
536}
537
547void proc_fd_install(struct proc *proc, int fd, struct file *file, int flags)
548{
549 proc->fds[fd] = (struct fd) {.file = file, .flags = flags};
550}
551
560struct file *proc_fd_file(struct proc *proc, int fd)
561{
562 if (fd < 0 || fd >= FDS_COUNT)
563 return NULL;
564
565 struct file *file = proc->fds[fd].file;
566 return file == FD_RESERVED ? NULL : file;
567}
568
578int proc_fd_close(struct proc *proc, int fd)
579{
580 struct file *file = proc_fd_file(proc, fd);
581
582 if (!file)
583 return -EBADF;
584
585 proc->fds[fd] = (struct fd) {0};
586 return file_put(file);
587}
588
597{
598 int err = 0;
599 struct session *session = NULL;
600 struct pgroup *pgrp = NULL;
601
602 /* the session */
603 session = kmalloc(sizeof(struct session), &M_SESSION, M_ZERO);
604 if (!session) goto e_nomem;
605
606 /* its process group */
607 pgrp = kmalloc(sizeof(struct pgroup), &M_PGROUP, M_ZERO);
608 if (!pgrp) goto e_nomem;
609
610 session->pgps = queue_new();
611 if (!session->pgps) goto e_nomem;
612
613 pgrp->procs = queue_new();
614 if (!pgrp->procs) goto e_nomem;
615
616 pgrp->session_node = enqueue(session->pgps, pgrp);
617 if (!pgrp->session_node) goto e_nomem;
618
619 /* the process's place in its old group is kept until this can't fail
620 * anymore (setsid() takes it back on failure) */
621 struct qnode *node = enqueue(pgrp->procs, proc);
622 if (!node) goto e_nomem;
623
624 proc->pgrp_node = node;
625
626 session->sid = proc->pid;
627 pgrp->pgid = proc->pid;
628
630 pgrp->leader = proc;
631
632 pgrp->session = session;
633 proc->pgrp = pgrp;
634
635 return 0;
636
637e_nomem:
638 err = -ENOMEM;
639error:
640 if (session) {
641 /* the group may be on the session's list already */
642 if (pgrp && pgrp->session_node)
643 queue_node_remove(session->pgps, pgrp->session_node);
644
646 kfree(session);
647 }
648
649 if (pgrp) {
650 kfree(pgrp->procs);
651 kfree(pgrp);
652 }
653
654 return err;
655}
656
667int proc_setpgid(struct proc *proc, pid_t pgid)
668{
669 struct session *session = proc->pgrp->session;
670 struct pgroup *pgrp = NULL;
671 int made = 0;
672
673 if (proc->pgrp->pgid == pgid)
674 return 0;
675
676 queue_for (node, session->pgps) {
677 struct pgroup *pg = node->value;
678
679 if (pg->pgid == pgid) {
680 pgrp = pg;
681 break;
682 }
683 }
684
685 if ((!pgrp || !pgrp->procs->count) && pgid != proc->pid)
686 return -EPERM;
687
688 if (!pgrp) {
689 if (!(pgrp = kmalloc(sizeof(struct pgroup), &M_PGROUP, M_ZERO)))
690 return -ENOMEM;
691
692 pgrp->pgid = pgid;
693 pgrp->session = session;
694
695 if (!(pgrp->procs = queue_new())) {
696 kfree(pgrp);
697 return -ENOMEM;
698 }
699
700 if (!(pgrp->session_node = enqueue(session->pgps, pgrp))) {
701 kfree(pgrp->procs);
702 kfree(pgrp);
703 return -ENOMEM;
704 }
705
706 made = 1;
707 }
708
709 struct qnode *node = enqueue(pgrp->procs, proc);
710
711 if (!node) {
712 /* a group made for the process goes again, empty */
713 if (made) {
714 queue_node_remove(session->pgps, pgrp->session_node);
715 kfree(pgrp->procs);
716 kfree(pgrp);
717 }
718
719 return -ENOMEM;
720 }
721
722 if (pgid == proc->pid)
723 pgrp->leader = proc;
724
725 struct pgroup *old = proc->pgrp;
726
727 queue_node_remove(old->procs, proc->pgrp_node);
728 proc->pgrp_node = node;
729 proc->pgrp = pgrp;
730
731 pgrp_release(old);
732 return 0;
733}
734
742void pgrp_release(struct pgroup *pgrp)
743{
744 if (pgrp->procs->count)
745 return;
746
747 struct session *session = pgrp->session;
748
749 if (session->ctty && session->ctty->fg == pgrp)
750 session->ctty->fg = NULL;
751
752 queue_node_remove(session->pgps, pgrp->session_node);
753 kfree(pgrp->procs);
754 kfree(pgrp);
755
756 if (session->pgps->count)
757 return;
758
759 if (session->ctty) {
761 session->ctty->fg = NULL;
762 }
763
765 kfree(session);
766}
static void arch_interrupts_disable(void)
Masks IRQs.
Definition arch.h:77
void arch_cur_thread_kill(void)
Ends the current thread.
Definition sched.c:87
#define panic(s)
Definition panic.h:15
#define BITMAP_NEW(n)
Definition bitmap.h:33
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
Definition close.c:18
int file_put(struct file *file)
Drops a reference to an open file.
Definition file.c:60
void thread_files_release(struct thread *thread)
Lets go of the open files a thread's system call held, when the call returns or the thread is killed.
Definition file.c:99
void tty_hangup(struct tty *tty)
Hangs up a controlling terminal, when its session ends (its leader exited) or the terminal goes away:...
Definition generic.c:668
#define FDS_COUNT
Definition config.h:46
#define MALLOC_DEFINE(type, _name, _desc)
Definition kvmem.h:30
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
#define M_ZERO
Definition kvmem.h:26
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void pmap_decref(struct pmap *pmap)
Drops a reference to an address space's page tables, freeing them with the last one.
Definition pmap.c:271
struct pmap * pmap_create(void)
Makes the page tables of a new address space: an empty user half, and the kernel's half,...
Definition pmap.c:242
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
int proc_fd_get(struct proc *proc)
Reserves the lowest free descriptor of a process, while a system call sets it up: no other thread tak...
Definition proc.c:514
void proc_threads_exec(struct proc *proc)
Ends every thread of a process but the current one, for execve() (POSIX: they run in the program that...
Definition proc.c:358
int proc_fd_close(struct proc *proc, int fd)
Closes a descriptor: it is free again, and its reference to the open file is dropped.
Definition proc.c:578
void proc_pid_free(int pid)
Frees a process ID.
Definition proc.c:102
int proc_reap(struct proc *proc)
Frees a zombie, once its parent waited for it (or doesn't wait for its children).
Definition proc.c:484
int proc_init(struct proc *proc)
Gives a new process (init) its ID and its descriptor table.
Definition proc.c:197
struct queue * sessions
Definition proc.c:42
int proc_threads_end(struct proc *proc, struct thread *keep, int exiting)
Ends the threads of a process, but one.
Definition proc.c:305
#define FD_RESERVED
Definition proc.h:53
struct file * proc_fd_file(struct proc *proc, int fd)
Finds the open file a descriptor refers to.
Definition proc.c:560
pid_t proc_pid_alloc(void)
Allocates a process ID, from 1 (init's) on.
Definition proc.c:80
void proc_fd_release(struct proc *proc, int fd)
Frees a reserved descriptor that wasn't set up after all.
Definition proc.c:532
int pgrp_orphaned(struct pgroup *pgrp, struct proc *gone)
Says whether a process group is orphaned (POSIX): none of its members has a parent in another group o...
Definition proc.c:227
int proc_new(struct proc **ref)
Makes a new process structure, with one thread and an empty address space, on the list of every proce...
Definition proc.c:114
struct proc * proc_pid_find(pid_t pid)
Finds a process by its ID.
Definition proc.c:179
int session_new(struct proc *proc)
Makes a new session, with a new process group, both led by a process and with its ID,...
Definition proc.c:596
void proc_fd_install(struct proc *proc, int fd, struct file *file, int flags)
Makes a reserved descriptor refer to an open file.
Definition proc.c:547
int proc_setpgid(struct proc *proc, pid_t pgid)
Moves a process into a process group of its session, as setpgid() does.
Definition proc.c:667
struct queue * procs
Definition proc.c:37
struct proc * initproc
Definition proc.c:39
void proc_kill(struct proc *proc)
Ends a process: its threads end, its descriptors are closed, its memory is freed, its children go to ...
Definition proc.c:375
void pgrp_release(struct pgroup *pgrp)
Frees a process group if no process is left in it, and its session if that was the session's last gro...
Definition proc.c:742
void arch_reboot(void)
Restarts the machine.
Definition psci.c:25
#define queue_for(n, q)
Definition queue.h:37
#define QUEUE_NEW()
Definition queue.h:40
void sched_timer_cancel(struct thread *thread)
Takes a thread off the list of threads waiting with a deadline, when it no longer waits (it was woken...
Definition sched.c:173
void sched_alarm(struct proc *proc, uint64_t value, uint64_t interval, uint64_t *old_value, uint64_t *old_interval)
Sets a process's real time timer, which setitimer() and alarm() use: the process gets SIGALRM once va...
Definition sched.c:144
#define curthread
Definition sched.h:12
struct cpu * sched_thread_cpu(struct thread *thread)
Finds the CPU that is running a thread, if it's another CPU than this one.
Definition sched.c:229
void sched_thread_kick(struct thread *thread)
Makes a thread that runs on another CPU enter the kernel now, rather than at its next tick: a signal ...
Definition sched.c:244
#define SIG_MAX
Definition signal.h:16
int signal_proc_send(struct proc *proc, int signal)
Sends a signal to a process.
Definition signal.c:310
#define SIG_DFL
Definition signal.h:26
#define SIG_IGN
Definition signal.h:27
int signal_pgrp_send(struct pgroup *pg, int signal)
Sends a signal to every process of a process group.
Definition signal.c:322
#define NULL
Definition stddef.h:27
A bitmap: its blocks, and its last bit's index.
Definition bitmap.h:17
size_t max_idx
Definition bitmap.h:19
A file descriptor: the open file it refers to (fs/file.c, shared with the descriptors that dup() and ...
Definition proc.h:47
int flags
Definition proc.h:49
struct file * file
Definition proc.h:48
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
int flags
Definition vfs.h:164
A process group: the processes of a job.
Definition proc.h:56
struct proc * leader
its leader, the process whose PID is its ID
Definition proc.h:70
struct queue * procs
its processes
Definition proc.h:67
struct session * session
its session
Definition proc.h:61
pid_t pgid
the group's ID
Definition proc.h:58
struct qnode * session_node
its node on its session's list
Definition proc.h:64
An address space's page tables, on x86.
Definition pmap.h:9
size_t ref
Definition pmap.h:11
A process.
Definition proc.h:75
pid_t pid
the process's ID
Definition proc.h:77
struct proc * parent
its parent
Definition proc.h:90
struct aquila_sigaction sigaction[SIG_MAX+1]
its signal actions
Definition proc.h:157
struct qnode * pgrp_node
Definition proc.h:81
uint64_t cstime
Definition proc.h:109
uint64_t utime
its CPU time in user mode and in the kernel (ns), and that of the children it waited for
Definition proc.h:108
struct waitq wait_queue
a parent waiting for a child (waitpid()) sleeps here
Definition proc.h:154
uint64_t stime
Definition proc.h:108
struct vm_space vm_space
its address space
Definition proc.h:129
struct waitq thread_join
threads waiting in thread_join() sleep here
Definition proc.h:143
int exit
its exit status (PROC_EXIT())
Definition proc.h:160
struct vnode * cwd
its current directory (a reference), or NULL for the root
Definition proc.h:93
uint64_t cutime
Definition proc.h:109
int stopped
the signal that stopped it, or 0; and what waitpid() has to report (WAIT_*)
Definition proc.h:100
int running
whether it's running
Definition proc.h:163
struct fd * fds
its file descriptors (FDS_COUNT of them)
Definition proc.h:87
char * name
its name: the program it runs
Definition proc.h:84
struct queue threads
its threads
Definition proc.h:136
sigset_t sig_pending
its pending signals, a bit (1 << sig) each: a signal sent again while it's pending is delivered once ...
Definition proc.h:148
struct pgroup * pgrp
its process group, and its node on the group's list
Definition proc.h:80
int zombie
proc_kill() is done with it, so it can be reaped (that isn't as soon as it stops running: closing its...
Definition proc.h:167
A queue's node, holding one entry.
Definition queue.h:19
void * value
Definition queue.h:20
struct qnode * next
Definition queue.h:22
A queue.
Definition queue.h:29
size_t count
Definition queue.h:30
struct qnode * head
Definition queue.h:31
A session: its process groups, and its controlling terminal.
Definition proc.h:26
struct queue * pgps
its process groups
Definition proc.h:31
struct tty * ctty
its controlling terminal, or NULL
Definition proc.h:37
struct proc * leader
its leader, the process that made it
Definition proc.h:34
pid_t sid
the session's ID
Definition proc.h:28
A thread.
Definition thread.h:23
struct list_node run_link
it's on the ready list (sched.c) while it's ready to run, or on the wait queue it sleeps on (waitq); ...
Definition thread.h:45
state_t state
its state
Definition thread.h:28
int killed
it was killed (proc_threads_end()) while it ran on another CPU: it frees itself there,...
Definition thread.h:101
struct waitq * waitq
Definition thread.h:46
struct proc * owner
its process
Definition thread.h:31
struct pgroup * fg
the foreground process group, or NULL
Definition tty.h:63
struct session * session
the session it is the controlling terminal of, or NULL
Definition tty.h:60
An address space: its mappings, and its page tables.
Definition vm.h:25
struct pmap * pmap
its page tables (the architecture's)
Definition vm.h:27
static void pgrp_orphaned_hangup(struct pgroup *pgrp, struct proc *gone)
Sends SIGHUP and SIGCONT to a process group that gone leaving makes orphaned, if one of its members i...
Definition proc.c:245
static int pgrp_other_same_session(struct proc *p, struct proc *q)
Returns whether p's process group is another group of the same session as q's.
Definition proc.c:264
static int pid_is_group(int pid)
Returns whether a process group or a session has pid as its ID.
Definition proc.c:56
struct bitmap * pid_bitmap
Definition proc.c:45
static void proc_zombie_notify(struct proc *proc)
Tells a zombie's parent that it ended: its wait() wakes up and it gets SIGCHLD.
Definition proc.c:272
static int last_pid
Definition proc.c:51
int thread_kill(struct thread *thread)
Releases what a thread holds (its poll() registrations, its CPU state and kernel stack) and makes it ...
Definition thread.c:59
int thread_new(struct proc *proc, struct thread **rthread)
Makes a new thread in a process.
Definition thread.c:27
@ ZOMBIE
Definition thread.h:19
int pid_t
Definition types.h:8
struct vm_space kvm_space
Definition vmm.c:17
void vm_space_destroy(struct vm_space *vm_space)
Removes all the mappings of an address space: its entries are released and freed, and its page tables...
Definition vm_space.c:124
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
Definition waitq.c:178
void waitq_sleep_unint(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up, whatever signals come meanwhil...
Definition waitq.c:67