blob: 236d13ac20c44fb3e16dbbe02a4f0a3a2dd34685 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include "Process.class.h"
#include <TaskManager/Task.ns.h>
#include <MemoryManager/PhysMem.ns.h>
#include <VFS/File.class.h>
Process::Process() { //Private constructor, does nothing
}
Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
Process* p = new Process();
p->m_pid = 0;
p->m_cmdline = cmdline;
p->m_retval = 0;
p->m_state = P_RUNNING;
p->m_pagedir = kernelPageDirectory;
p->m_uid = 0;
p->m_stacksstart = 0;
p->m_vt = vt;
Thread* t = new Thread();
t->m_process = p;
t->m_state = T_RUNNING;
t->m_isKernel = true;
t->m_kernelStackFrame = 0;
p->registerThread(t);
Task::registerProcess(p);
Task::registerThread(t);
return p;
}
Process::Process(String cmdline, u32int uid) {
m_pid = Task::nextPid();
m_cmdline = cmdline;
m_retval = 0;
m_state = P_RUNNING;
m_pagedir = new PageDirectory(kernelPageDirectory);
m_uid = uid;
m_vt = Task::currentProcess->getVirtualTerminal();
m_stacksstart = 0xC0000000;
}
Process::~Process() {
exit(); //Kill all threads
delete m_pagedir;
}
u32int Process::stackAlloc() {
if (m_stacksstart < STACKSIZE) return 0;
for (u32int i = m_stacksstart - STACKSIZE; i < m_stacksstart; i += 0x1000) {
m_pagedir->allocFrame(i & 0xFFFFF000, true, true);
}
m_stacksstart -= STACKSIZE;
return m_stacksstart;
}
void Process::exit() {
for (u32int i = 0; i < m_threads.size(); i++) {
delete m_threads[i];
}
m_threads.clear();
for (u32int i = 0; i < m_fileDescriptors.size(); i++) {
m_fileDescriptors[i]->close(false);
delete m_fileDescriptors[i];
}
m_fileDescriptors.clear();
m_state = P_FINISHED;
}
void Process::registerThread(Thread* t) {
if (m_state != P_FINISHED)
m_threads.push(t);
}
void Process::threadFinishes(Thread* thread, u32int retval) {
// If it is the main thread of the process, or if it pagefaulted
if (thread == m_threads[0] or retval == E_PAGEFAULT) {
exit();
} else {
//Simply unregister thread
for (u32int i = 0; i < m_threads.size(); i++) {
if (m_threads[i] == thread) {
m_threads[i] = m_threads.back();
m_threads.pop();
break;
}
}
delete thread;
}
}
void Process::registerFileDescriptor(File* fd) {
m_fileDescriptors.push(fd);
}
void Process::unregisterFileDescriptor(File* fd) {
for (u32int i = 0; i < m_fileDescriptors.size(); i++) {
if (m_fileDescriptors[i] == fd) {
m_fileDescriptors[i] = m_fileDescriptors.back();
m_fileDescriptors.pop();
break;
}
}
}
PageDirectory* Process::getPagedir() {
return m_pagedir;
}
VirtualTerminal* Process::getVirtualTerminal() {
return m_vt;
}
void Process::setVirtualTerminal(VirtualTerminal* vt) {
m_vt = vt;
}
|