mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
Unify the Task constructors.
There's now Task::create() and Task::createKernelTask().
This commit is contained in:
parent
dff516f6d0
commit
434b6a8688
Notes:
sideshowbarker
2024-07-19 18:39:02 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/434b6a86883
3 changed files with 60 additions and 127 deletions
168
Kernel/Task.cpp
168
Kernel/Task.cpp
|
@ -57,7 +57,7 @@ void Task::initialize()
|
|||
next_pid = 0;
|
||||
s_tasks = new InlineLinkedList<Task>;
|
||||
s_deadTasks = new InlineLinkedList<Task>;
|
||||
s_kernelTask = new Task(0, "colonel", Task::Ring0);
|
||||
s_kernelTask = Task::createKernelTask(nullptr, "colonel");
|
||||
redoKernelTaskTSS();
|
||||
loadTaskRegister(s_kernelTask->selector());
|
||||
}
|
||||
|
@ -166,13 +166,13 @@ int Task::sys$munmap(void* addr, size_t size)
|
|||
|
||||
int Task::sys$spawn(const char* path)
|
||||
{
|
||||
auto* child = Task::create(path, m_uid, m_gid, m_pid);
|
||||
auto* child = Task::createUserTask(path, m_uid, m_gid, m_pid);
|
||||
if (child)
|
||||
return child->pid();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Task* Task::create(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
|
||||
Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
|
||||
{
|
||||
auto parts = path.split('/');
|
||||
if (parts.isEmpty())
|
||||
|
@ -187,7 +187,7 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
|
|||
return nullptr;
|
||||
|
||||
InterruptDisabler disabler; // FIXME: Get rid of this, jesus christ. This "critical" section is HUGE.
|
||||
Task* t = new Task(parts.takeLast(), uid, gid, parentPID);
|
||||
Task* t = new Task(parts.takeLast(), uid, gid, parentPID, Ring3);
|
||||
|
||||
ExecSpace space;
|
||||
space.hookableAlloc = [&] (const String& name, size_t size) {
|
||||
|
@ -224,18 +224,35 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
|
|||
return t;
|
||||
}
|
||||
|
||||
Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID)
|
||||
Task* Task::createKernelTask(void (*e)(), String&& name)
|
||||
{
|
||||
Task* task = new Task(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
|
||||
task->m_tss.eip = (dword)e;
|
||||
|
||||
if (task->pid() != 0) {
|
||||
InterruptDisabler disabler;
|
||||
s_tasks->prepend(task);
|
||||
system.nprocess++;
|
||||
#ifdef TASK_DEBUG
|
||||
kprintf("Kernel task %u (%s) spawned @ %p\n", task->pid(), task->name().characters(), task->m_tss.eip);
|
||||
#endif
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel ring)
|
||||
: m_name(move(name))
|
||||
, m_pid(next_pid++)
|
||||
, m_uid(uid)
|
||||
, m_gid(gid)
|
||||
, m_state(Runnable)
|
||||
, m_ring(Ring3)
|
||||
, m_ring(ring)
|
||||
, m_parentPID(parentPID)
|
||||
{
|
||||
m_fileHandles.append(nullptr);
|
||||
m_fileHandles.append(nullptr);
|
||||
m_fileHandles.append(nullptr);
|
||||
m_fileHandles.append(nullptr); // stdin
|
||||
m_fileHandles.append(nullptr); // stdout
|
||||
m_fileHandles.append(nullptr); // stderr
|
||||
|
||||
auto* parentTask = Task::fromPID(parentPID);
|
||||
if (parentTask)
|
||||
|
@ -246,113 +263,39 @@ Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID)
|
|||
m_nextRegion = LinearAddress(0x600000);
|
||||
|
||||
memset(&m_tss, 0, sizeof(m_tss));
|
||||
memset(&m_ldtEntries, 0, sizeof(m_ldtEntries));
|
||||
|
||||
allocateLDT();
|
||||
|
||||
// Only IF is set when a task boots.
|
||||
m_tss.eflags = 0x0202;
|
||||
|
||||
WORD codeSegment = 0x1b;
|
||||
WORD dataSegment = 0x23;
|
||||
WORD stackSegment = dataSegment;
|
||||
|
||||
m_tss.ds = dataSegment;
|
||||
m_tss.es = dataSegment;
|
||||
m_tss.fs = dataSegment;
|
||||
m_tss.gs = dataSegment;
|
||||
m_tss.ss = stackSegment;
|
||||
m_tss.cs = codeSegment;
|
||||
|
||||
m_tss.cr3 = MemoryManager::the().pageDirectoryBase().get();
|
||||
|
||||
auto* region = allocateRegion(defaultStackSize, "stack");
|
||||
ASSERT(region);
|
||||
m_stackTop = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
|
||||
m_tss.esp = m_stackTop;
|
||||
|
||||
// Set up a separate stack for Ring0.
|
||||
m_kernelStack = kmalloc(defaultStackSize);
|
||||
DWORD ring0StackTop = ((DWORD)m_kernelStack + defaultStackSize) & 0xffffff8;
|
||||
m_tss.ss0 = 0x10;
|
||||
m_tss.esp0 = ring0StackTop;
|
||||
|
||||
// HACK: Ring2 SS in the TSS is the current PID.
|
||||
m_tss.ss2 = m_pid;
|
||||
|
||||
m_farPtr.offset = 0x98765432;
|
||||
|
||||
ASSERT(m_pid);
|
||||
}
|
||||
|
||||
Task::Task(void (*e)(), const char* n, RingLevel ring)
|
||||
: m_name(n)
|
||||
, m_entry(e)
|
||||
, m_pid(next_pid++)
|
||||
, m_state(Runnable)
|
||||
, m_ring(ring)
|
||||
{
|
||||
m_fileHandles.append(nullptr);
|
||||
m_fileHandles.append(nullptr);
|
||||
m_fileHandles.append(nullptr);
|
||||
|
||||
m_cwd = "/";
|
||||
|
||||
m_nextRegion = LinearAddress(0x600000);
|
||||
|
||||
Region* codeRegion = nullptr;
|
||||
if (!isRing0()) {
|
||||
codeRegion = allocateRegion(4096, "code");
|
||||
ASSERT(codeRegion);
|
||||
bool success = copyToZone(*codeRegion->zone, (void*)e, PAGE_SIZE);
|
||||
ASSERT(success);
|
||||
}
|
||||
|
||||
memset(&m_tss, 0, sizeof(m_tss));
|
||||
memset(&m_ldtEntries, 0, sizeof(m_ldtEntries));
|
||||
|
||||
if (ring == Ring3) {
|
||||
if (isRing3()) {
|
||||
memset(&m_ldtEntries, 0, sizeof(m_ldtEntries));
|
||||
allocateLDT();
|
||||
}
|
||||
|
||||
// Only IF is set when a task boots.
|
||||
m_tss.eflags = 0x0202;
|
||||
|
||||
WORD dataSegment;
|
||||
WORD stackSegment;
|
||||
WORD codeSegment;
|
||||
word cs, ds, ss;
|
||||
|
||||
if (ring == Ring0) {
|
||||
codeSegment = 0x08;
|
||||
dataSegment = 0x10;
|
||||
stackSegment = dataSegment;
|
||||
if (isRing0()) {
|
||||
cs = 0x08;
|
||||
ds = 0x10;
|
||||
ss = 0x10;
|
||||
} else {
|
||||
codeSegment = 0x1b;
|
||||
dataSegment = 0x23;
|
||||
stackSegment = dataSegment;
|
||||
cs = 0x1b;
|
||||
ds = 0x23;
|
||||
ss = 0x23;
|
||||
}
|
||||
|
||||
m_tss.ds = dataSegment;
|
||||
m_tss.es = dataSegment;
|
||||
m_tss.fs = dataSegment;
|
||||
m_tss.gs = dataSegment;
|
||||
m_tss.ss = stackSegment;
|
||||
m_tss.cs = codeSegment;
|
||||
|
||||
ASSERT((codeSegment & 3) == (stackSegment & 3));
|
||||
m_tss.ds = ds;
|
||||
m_tss.es = ds;
|
||||
m_tss.fs = ds;
|
||||
m_tss.gs = ds;
|
||||
m_tss.ss = ss;
|
||||
m_tss.cs = cs;
|
||||
|
||||
m_tss.cr3 = MemoryManager::the().pageDirectoryBase().get();
|
||||
|
||||
if (isRing0()) {
|
||||
m_tss.eip = (DWORD)m_entry;
|
||||
} else {
|
||||
m_tss.eip = codeRegion->linearAddress.get();
|
||||
}
|
||||
|
||||
if (isRing0()) {
|
||||
// FIXME: This memory is leaked.
|
||||
// But uh, there's also no kernel task termination, so I guess it's not technically leaked...
|
||||
|
||||
dword stackBottom = (dword)kmalloc(defaultStackSize);
|
||||
m_stackTop = (stackBottom + defaultStackSize) & 0xffffff8;
|
||||
m_tss.esp = m_stackTop;
|
||||
|
@ -360,12 +303,11 @@ Task::Task(void (*e)(), const char* n, RingLevel ring)
|
|||
auto* region = allocateRegion(defaultStackSize, "stack");
|
||||
ASSERT(region);
|
||||
m_stackTop = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
|
||||
m_tss.esp = m_stackTop;
|
||||
}
|
||||
m_tss.esp = m_stackTop;
|
||||
|
||||
if (ring == Ring3) {
|
||||
// Set up a separate stack for Ring0.
|
||||
// FIXME: Don't leak this stack either.
|
||||
if (isRing3()) {
|
||||
// Ring3 tasks need a separate stack for Ring0.
|
||||
m_kernelStack = kmalloc(defaultStackSize);
|
||||
DWORD ring0StackTop = ((DWORD)m_kernelStack + defaultStackSize) & 0xffffff8;
|
||||
m_tss.ss0 = 0x10;
|
||||
|
@ -374,25 +316,12 @@ Task::Task(void (*e)(), const char* n, RingLevel ring)
|
|||
|
||||
// HACK: Ring2 SS in the TSS is the current PID.
|
||||
m_tss.ss2 = m_pid;
|
||||
|
||||
m_farPtr.offset = 0x12345678;
|
||||
|
||||
// Don't add task 0 (kernel dummy task) to task list.
|
||||
// FIXME: This doesn't belong in the constructor.
|
||||
if (m_pid == 0)
|
||||
return;
|
||||
|
||||
// Add it to head of task list (meaning it's next to run too, ATM.)
|
||||
s_tasks->prepend(this);
|
||||
|
||||
system.nprocess++;
|
||||
#ifdef TASK_DEBUG
|
||||
kprintf("Task %u (%s) spawned @ %p\n", m_pid, m_name.characters(), m_tss.eip);
|
||||
#endif
|
||||
m_farPtr.offset = 0x98765432;
|
||||
}
|
||||
|
||||
Task::~Task()
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
system.nprocess--;
|
||||
delete [] m_ldtEntries;
|
||||
m_ldtEntries = nullptr;
|
||||
|
@ -462,6 +391,9 @@ void Task::taskDidCrash(Task* crashedTask)
|
|||
|
||||
void Task::doHouseKeeping()
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
if (s_deadTasks->isEmpty())
|
||||
return;
|
||||
Task* next = nullptr;
|
||||
for (auto* deadTask = s_deadTasks->head(); deadTask; deadTask = next) {
|
||||
next = deadTask->next();
|
||||
|
|
|
@ -15,8 +15,9 @@ class Zone;
|
|||
class Task : public InlineLinkedListNode<Task> {
|
||||
friend class InlineLinkedListNode<Task>;
|
||||
public:
|
||||
static Task* create(const String& path, uid_t, gid_t, pid_t parentPID);
|
||||
Task(String&& name, uid_t, gid_t, pid_t parentPID);
|
||||
static Task* createKernelTask(void (*entry)(), String&& name);
|
||||
static Task* createUserTask(const String& path, uid_t, gid_t, pid_t parentPID);
|
||||
~Task();
|
||||
|
||||
static Vector<Task*> allTasks();
|
||||
|
||||
|
@ -43,13 +44,11 @@ public:
|
|||
};
|
||||
|
||||
bool isRing0() const { return m_ring == Ring0; }
|
||||
bool isRing3() const { return m_ring == Ring3; }
|
||||
|
||||
static Task* fromPID(pid_t);
|
||||
static Task* kernelTask();
|
||||
|
||||
Task(void (*entry)(), const char* name, RingLevel);
|
||||
~Task();
|
||||
|
||||
const String& name() const { return m_name; }
|
||||
pid_t pid() const { return m_pid; }
|
||||
DWORD ticks() const { return m_ticks; }
|
||||
|
@ -117,6 +116,8 @@ public:
|
|||
private:
|
||||
friend class MemoryManager;
|
||||
|
||||
Task(String&& name, uid_t, gid_t, pid_t parentPID, RingLevel);
|
||||
|
||||
FileHandle* openFile(String&&);
|
||||
|
||||
void allocateLDT();
|
||||
|
|
|
@ -140,7 +140,7 @@ static void init_stage2()
|
|||
dword lastAlloc = sum_alloc;
|
||||
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
auto* shTask = Task::create("/bin/id", (uid_t)100, (gid_t)100);
|
||||
auto* shTask = Task::createUserTask("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0);
|
||||
kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
|
||||
kprintf("sizeof(Task):%u\n", sizeof(Task));
|
||||
kprintf("delta:%u\n",sum_alloc - lastAlloc);
|
||||
|
@ -149,7 +149,7 @@ static void init_stage2()
|
|||
}
|
||||
#endif
|
||||
|
||||
auto* shTask = Task::create("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0);
|
||||
auto* shTask = Task::createUserTask("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0);
|
||||
|
||||
banner();
|
||||
|
||||
|
@ -196,9 +196,9 @@ void init()
|
|||
|
||||
Task::initialize();
|
||||
|
||||
new Task(undertaker_main, "undertaker", Task::Ring0);
|
||||
Task::createKernelTask(undertaker_main, "undertaker");
|
||||
Task::createKernelTask(init_stage2, "init");
|
||||
|
||||
auto* init2 = new Task(init_stage2, "init", Task::Ring0);
|
||||
scheduleNewTask();
|
||||
|
||||
sti();
|
||||
|
|
Loading…
Reference in a new issue