Refactor process id allocation and accounting.
This commit is contained in:
parent
25e07a9083
commit
400eb2238f
|
@ -89,8 +89,8 @@ dispmsg.o \
|
||||||
dtable.o \
|
dtable.o \
|
||||||
elf.o \
|
elf.o \
|
||||||
fcache.o \
|
fcache.o \
|
||||||
fsfunc.o \
|
|
||||||
fs/full.o \
|
fs/full.o \
|
||||||
|
fsfunc.o \
|
||||||
fs/kram.o \
|
fs/kram.o \
|
||||||
fs/null.o \
|
fs/null.o \
|
||||||
fs/user.o \
|
fs/user.o \
|
||||||
|
@ -122,6 +122,7 @@ pci.o \
|
||||||
pipe.o \
|
pipe.o \
|
||||||
poll.o \
|
poll.o \
|
||||||
process.o \
|
process.o \
|
||||||
|
ptable.o \
|
||||||
refcount.o \
|
refcount.o \
|
||||||
registers.o \
|
registers.o \
|
||||||
resource.o \
|
resource.o \
|
||||||
|
|
|
@ -50,6 +50,7 @@ class Process;
|
||||||
class Descriptor;
|
class Descriptor;
|
||||||
class DescriptorTable;
|
class DescriptorTable;
|
||||||
class MountTable;
|
class MountTable;
|
||||||
|
class ProcessTable;
|
||||||
struct ProcessSegment;
|
struct ProcessSegment;
|
||||||
struct ProcessTimer;
|
struct ProcessTimer;
|
||||||
struct ioctx_struct;
|
struct ioctx_struct;
|
||||||
|
@ -68,9 +69,6 @@ public:
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
|
|
||||||
private:
|
|
||||||
static pid_t AllocatePID();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
char* string_table;
|
char* string_table;
|
||||||
size_t string_table_length;
|
size_t string_table_length;
|
||||||
|
@ -97,6 +95,9 @@ private:
|
||||||
Ref<MountTable> mtable;
|
Ref<MountTable> mtable;
|
||||||
Ref<DescriptorTable> dtable;
|
Ref<DescriptorTable> dtable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ref<ProcessTable> ptable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
kthread_mutex_t resource_limits_lock;
|
kthread_mutex_t resource_limits_lock;
|
||||||
struct rlimit resource_limits[RLIMIT_NUM_DECLARED];
|
struct rlimit resource_limits[RLIMIT_NUM_DECLARED];
|
||||||
|
@ -110,8 +111,9 @@ public:
|
||||||
public:
|
public:
|
||||||
void BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable);
|
void BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable);
|
||||||
void BootstrapDirectories(Ref<Descriptor> root);
|
void BootstrapDirectories(Ref<Descriptor> root);
|
||||||
Ref<MountTable> GetMTable();
|
|
||||||
Ref<DescriptorTable> GetDTable();
|
Ref<DescriptorTable> GetDTable();
|
||||||
|
Ref<MountTable> GetMTable();
|
||||||
|
Ref<ProcessTable> GetPTable();
|
||||||
Ref<Descriptor> GetRoot();
|
Ref<Descriptor> GetRoot();
|
||||||
Ref<Descriptor> GetCWD();
|
Ref<Descriptor> GetCWD();
|
||||||
Ref<Descriptor> GetDescriptor(int fd);
|
Ref<Descriptor> GetDescriptor(int fd);
|
||||||
|
@ -201,13 +203,6 @@ public:
|
||||||
public:
|
public:
|
||||||
void ResetForExecute();
|
void ResetForExecute();
|
||||||
|
|
||||||
public:
|
|
||||||
static Process* Get(pid_t pid);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool Put(Process* process);
|
|
||||||
static void Remove(Process* process);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Process* CurrentProcess();
|
Process* CurrentProcess();
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2014.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
sortix/kernel/ptable.h
|
||||||
|
Process table.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INCLUDE_SORTIX_KERNEl_PTABLE_H
|
||||||
|
#define INCLUDE_SORTIX_KERNEl_PTABLE_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sortix/kernel/kthread.h>
|
||||||
|
#include <sortix/kernel/refcount.h>
|
||||||
|
|
||||||
|
namespace Sortix {
|
||||||
|
|
||||||
|
class Process;
|
||||||
|
|
||||||
|
struct ptable_entry
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
Process* process;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProcessTable : public Refcountable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessTable();
|
||||||
|
virtual ~ProcessTable();
|
||||||
|
Process* Get(pid_t pid);
|
||||||
|
pid_t Allocate(Process* process);
|
||||||
|
void Free(pid_t pid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
kthread_mutex_t ptablelock;
|
||||||
|
pid_t next_pid;
|
||||||
|
struct ptable_entry* entries;
|
||||||
|
size_t entries_used;
|
||||||
|
size_t entries_length;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Sortix
|
||||||
|
|
||||||
|
#endif
|
|
@ -53,6 +53,7 @@
|
||||||
#include <sortix/kernel/panic.h>
|
#include <sortix/kernel/panic.h>
|
||||||
#include <sortix/kernel/pci.h>
|
#include <sortix/kernel/pci.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
#include <sortix/kernel/refcount.h>
|
#include <sortix/kernel/refcount.h>
|
||||||
#include <sortix/kernel/scheduler.h>
|
#include <sortix/kernel/scheduler.h>
|
||||||
#include <sortix/kernel/signal.h>
|
#include <sortix/kernel/signal.h>
|
||||||
|
@ -435,10 +436,16 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
|
||||||
DisplayMessage::Init();
|
DisplayMessage::Init();
|
||||||
|
|
||||||
// Now that the base system has been loaded, it's time to go threaded. First
|
// Now that the base system has been loaded, it's time to go threaded. First
|
||||||
// we create an object that represents this thread.
|
// we create an object that represents this process.
|
||||||
|
Ref<ProcessTable> ptable(new ProcessTable());
|
||||||
|
if ( !ptable )
|
||||||
|
Panic("Could not allocate the process table");
|
||||||
Process* system = new Process;
|
Process* system = new Process;
|
||||||
if ( !system )
|
if ( !system )
|
||||||
Panic("Could not allocate the system process");
|
Panic("Could not allocate the system process");
|
||||||
|
if ( (system->pid = (system->ptable = ptable)->Allocate(system)) < 0 )
|
||||||
|
Panic("Could not allocate the system process a pid");
|
||||||
|
ptable.Reset();
|
||||||
system->addrspace = Memory::GetAddressSpace();
|
system->addrspace = Memory::GetAddressSpace();
|
||||||
system->group = system;
|
system->group = system;
|
||||||
system->groupprev = NULL;
|
system->groupprev = NULL;
|
||||||
|
@ -658,7 +665,10 @@ static void BootThread(void* /*user*/)
|
||||||
if ( !initaddrspace ) { Panic("Could not create init's address space"); }
|
if ( !initaddrspace ) { Panic("Could not create init's address space"); }
|
||||||
|
|
||||||
Process* init = new Process;
|
Process* init = new Process;
|
||||||
if ( !init ) { Panic("Could not allocate init process"); }
|
if ( !init )
|
||||||
|
Panic("Could not allocate init process");
|
||||||
|
if ( (init->pid = (init->ptable = CurrentProcess()->ptable)->Allocate(init)) < 0 )
|
||||||
|
Panic("Could not allocate init a pid");
|
||||||
init->group = init;
|
init->group = init;
|
||||||
init->groupprev = NULL;
|
init->groupprev = NULL;
|
||||||
init->groupnext = NULL;
|
init->groupnext = NULL;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <sortix/kernel/kthread.h>
|
#include <sortix/kernel/kthread.h>
|
||||||
#include <sortix/kernel/poll.h>
|
#include <sortix/kernel/poll.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
#include <sortix/kernel/refcount.h>
|
#include <sortix/kernel/refcount.h>
|
||||||
#include <sortix/kernel/scheduler.h>
|
#include <sortix/kernel/scheduler.h>
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ int LogTerminal::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
||||||
int LogTerminal::tcsetpgrp(ioctx_t* /*ctx*/, pid_t pgid)
|
int LogTerminal::tcsetpgrp(ioctx_t* /*ctx*/, pid_t pgid)
|
||||||
{
|
{
|
||||||
ScopedLock lock(&termlock);
|
ScopedLock lock(&termlock);
|
||||||
Process* process = Process::Get(pgid);
|
Process* process = CurrentProcess()->GetPTable()->Get(pgid);
|
||||||
if ( !pgid || !process )
|
if ( !pgid || !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
kthread_mutex_lock(&process->groupchildlock);
|
kthread_mutex_lock(&process->groupchildlock);
|
||||||
|
@ -187,7 +188,7 @@ void LogTerminal::ProcessKeystroke(int kbkey)
|
||||||
{
|
{
|
||||||
while ( linebuffer.CanBackspace() )
|
while ( linebuffer.CanBackspace() )
|
||||||
linebuffer.Backspace();
|
linebuffer.Backspace();
|
||||||
if ( Process* process = Process::Get(foreground_pgid) )
|
if ( Process* process = CurrentProcess()->GetPTable()->Get(foreground_pgid) )
|
||||||
process->DeliverGroupSignal(SIGINT);
|
process->DeliverGroupSignal(SIGINT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
#include <sortix/kernel/mtable.h>
|
#include <sortix/kernel/mtable.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
#include <sortix/kernel/refcount.h>
|
#include <sortix/kernel/refcount.h>
|
||||||
#include <sortix/kernel/scheduler.h>
|
#include <sortix/kernel/scheduler.h>
|
||||||
#include <sortix/kernel/sortedlist.h>
|
#include <sortix/kernel/sortedlist.h>
|
||||||
|
@ -81,7 +82,7 @@ Process::Process()
|
||||||
symbol_table_length = 0;
|
symbol_table_length = 0;
|
||||||
program_image_path = NULL;
|
program_image_path = NULL;
|
||||||
addrspace = 0;
|
addrspace = 0;
|
||||||
pid = AllocatePID();
|
pid = 0;
|
||||||
|
|
||||||
nicelock = KTHREAD_MUTEX_INITIALIZER;
|
nicelock = KTHREAD_MUTEX_INITIALIZER;
|
||||||
nice = 0;
|
nice = 0;
|
||||||
|
@ -160,7 +161,6 @@ Process::Process()
|
||||||
// child_system_clock initialized in member constructor.
|
// child_system_clock initialized in member constructor.
|
||||||
Time::InitializeProcessClocks(this);
|
Time::InitializeProcessClocks(this);
|
||||||
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
|
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
|
||||||
Put(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::~Process()
|
Process::~Process()
|
||||||
|
@ -179,7 +179,9 @@ Process::~Process()
|
||||||
assert(!cwd);
|
assert(!cwd);
|
||||||
assert(!root);
|
assert(!root);
|
||||||
|
|
||||||
Remove(this);
|
assert(ptable);
|
||||||
|
ptable->Free(pid);
|
||||||
|
ptable.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable)
|
void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable)
|
||||||
|
@ -588,6 +590,13 @@ Ref<DescriptorTable> Process::GetDTable()
|
||||||
return dtable;
|
return dtable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<ProcessTable> Process::GetPTable()
|
||||||
|
{
|
||||||
|
ScopedLock lock(&ptrlock);
|
||||||
|
assert(ptable);
|
||||||
|
return ptable;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Descriptor> Process::GetRoot()
|
Ref<Descriptor> Process::GetRoot()
|
||||||
{
|
{
|
||||||
ScopedLock lock(&ptrlock);
|
ScopedLock lock(&ptrlock);
|
||||||
|
@ -634,6 +643,12 @@ Process* Process::Fork()
|
||||||
if ( !clone )
|
if ( !clone )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if ( (clone->pid = (clone->ptable = ptable)->Allocate(clone)) < 0 )
|
||||||
|
{
|
||||||
|
delete clone;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct segment* clone_segments = NULL;
|
struct segment* clone_segments = NULL;
|
||||||
|
|
||||||
// Fork the segment list.
|
// Fork the segment list.
|
||||||
|
@ -1299,7 +1314,7 @@ static pid_t sys_getppid()
|
||||||
|
|
||||||
static pid_t sys_getpgid(pid_t pid)
|
static pid_t sys_getpgid(pid_t pid)
|
||||||
{
|
{
|
||||||
Process* process = !pid ? CurrentProcess() : Process::Get(pid);
|
Process* process = !pid ? CurrentProcess() : CurrentProcess()->GetPTable()->Get(pid);
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
|
|
||||||
|
@ -1324,10 +1339,10 @@ static int sys_setpgid(pid_t pid, pid_t pgid)
|
||||||
// group. This probably unlikely, but correctness over all!
|
// group. This probably unlikely, but correctness over all!
|
||||||
|
|
||||||
// Find the processes in question.
|
// Find the processes in question.
|
||||||
Process* process = !pid ? CurrentProcess() : Process::Get(pid);
|
Process* process = !pid ? CurrentProcess() : CurrentProcess()->GetPTable()->Get(pid);
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
Process* group = !pgid ? process : Process::Get(pgid);
|
Process* group = !pgid ? process : CurrentProcess()->GetPTable()->Get(pgid);
|
||||||
if ( !group )
|
if ( !group )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
|
|
||||||
|
@ -1372,60 +1387,6 @@ static int sys_setpgid(pid_t pid, pid_t pgid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t nextpidtoallocate;
|
|
||||||
kthread_mutex_t pidalloclock;
|
|
||||||
|
|
||||||
pid_t Process::AllocatePID()
|
|
||||||
{
|
|
||||||
ScopedLock lock(&pidalloclock);
|
|
||||||
return nextpidtoallocate++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ProcessCompare(Process* a, Process* b)
|
|
||||||
{
|
|
||||||
if ( a->pid < b->pid )
|
|
||||||
return -1;
|
|
||||||
if ( a->pid > b->pid )
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ProcessPIDCompare(Process* a, pid_t pid)
|
|
||||||
{
|
|
||||||
if ( a->pid < pid )
|
|
||||||
return -1;
|
|
||||||
if ( a->pid > pid )
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SortedList<Process*>* pidlist;
|
|
||||||
|
|
||||||
Process* Process::Get(pid_t pid)
|
|
||||||
{
|
|
||||||
ScopedLock lock(&pidalloclock);
|
|
||||||
size_t index = pidlist->Search(ProcessPIDCompare, pid);
|
|
||||||
if ( index == SIZE_MAX )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return pidlist->Get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Process::Put(Process* process)
|
|
||||||
{
|
|
||||||
ScopedLock lock(&pidalloclock);
|
|
||||||
return pidlist->Add(process);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Process::Remove(Process* process)
|
|
||||||
{
|
|
||||||
ScopedLock lock(&pidalloclock);
|
|
||||||
size_t index = pidlist->Search(process);
|
|
||||||
assert(index != SIZE_MAX);
|
|
||||||
|
|
||||||
pidlist->Remove(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* sys_sbrk(intptr_t increment)
|
static void* sys_sbrk(intptr_t increment)
|
||||||
{
|
{
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
|
@ -1516,13 +1477,6 @@ void Process::Init()
|
||||||
Syscall::Register(SYSCALL_TFORK, (void*) sys_tfork);
|
Syscall::Register(SYSCALL_TFORK, (void*) sys_tfork);
|
||||||
Syscall::Register(SYSCALL_UMASK, (void*) sys_umask);
|
Syscall::Register(SYSCALL_UMASK, (void*) sys_umask);
|
||||||
Syscall::Register(SYSCALL_WAITPID, (void*) sys_waitpid);
|
Syscall::Register(SYSCALL_WAITPID, (void*) sys_waitpid);
|
||||||
|
|
||||||
pidalloclock = KTHREAD_MUTEX_INITIALIZER;
|
|
||||||
nextpidtoallocate = 0;
|
|
||||||
|
|
||||||
pidlist = new SortedList<Process*>(ProcessCompare);
|
|
||||||
if ( !pidlist )
|
|
||||||
Panic("could not allocate pidlist\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2014.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
ptable.cpp
|
||||||
|
Process table.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sortix/kernel/kthread.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
|
#include <sortix/kernel/refcount.h>
|
||||||
|
|
||||||
|
// TODO: Process memory ownership needs to be reference counted.
|
||||||
|
// TODO: There is no proper way to iterate all the existing processes.
|
||||||
|
// TODO: This implementation is rather run-time inefficient.
|
||||||
|
// TODO: The Free method potentially leaks memory as the ptable is never shrunk.
|
||||||
|
// TODO: The next_pid counter could potentially overflow.
|
||||||
|
|
||||||
|
namespace Sortix {
|
||||||
|
|
||||||
|
ProcessTable::ProcessTable()
|
||||||
|
{
|
||||||
|
ptablelock = KTHREAD_MUTEX_INITIALIZER;
|
||||||
|
next_pid = 0;
|
||||||
|
entries = NULL;
|
||||||
|
entries_used = 0;
|
||||||
|
entries_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessTable::~ProcessTable()
|
||||||
|
{
|
||||||
|
delete[] entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
Process* ProcessTable::Get(pid_t pid)
|
||||||
|
{
|
||||||
|
ScopedLock lock(&ptablelock);
|
||||||
|
for ( size_t i = 0; i < entries_used; i++ )
|
||||||
|
if ( entries[i].pid == pid )
|
||||||
|
return entries[i].process;
|
||||||
|
return errno = ESRCH, (Process*) NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t ProcessTable::Allocate(Process* process)
|
||||||
|
{
|
||||||
|
ScopedLock lock(&ptablelock);
|
||||||
|
if ( entries_used == entries_length )
|
||||||
|
{
|
||||||
|
size_t new_length = entries_length ? 2 * entries_length : 64;
|
||||||
|
struct ptable_entry* new_entries = new struct ptable_entry[new_length];
|
||||||
|
if ( !new_entries )
|
||||||
|
return -1;
|
||||||
|
memcpy(new_entries, entries, sizeof(struct ptable_entry) * entries_length);
|
||||||
|
delete[] entries;
|
||||||
|
entries = new_entries;
|
||||||
|
entries_length = new_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ptable_entry* entry = &entries[entries_used++];
|
||||||
|
entry->process = process;
|
||||||
|
return entry->pid = next_pid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessTable::Free(pid_t pid)
|
||||||
|
{
|
||||||
|
ScopedLock lock(&ptablelock);
|
||||||
|
for ( size_t i = 0; i < entries_used; i++ )
|
||||||
|
{
|
||||||
|
if ( entries[i].pid != pid )
|
||||||
|
continue;
|
||||||
|
entries[i] = entries[--entries_used];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Sortix
|
|
@ -32,6 +32,7 @@
|
||||||
#include <sortix/kernel/copy.h>
|
#include <sortix/kernel/copy.h>
|
||||||
#include <sortix/kernel/kernel.h>
|
#include <sortix/kernel/kernel.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
#include <sortix/kernel/syscall.h>
|
#include <sortix/kernel/syscall.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
@ -45,7 +46,7 @@ static int GetProcessPriority(pid_t who)
|
||||||
return errno = EINVAL, -1;
|
return errno = EINVAL, -1;
|
||||||
// TODO: If who isn't the current process, then it could self-destruct at
|
// TODO: If who isn't the current process, then it could self-destruct at
|
||||||
// any time while we use it; there is no safe way to do this yet.
|
// any time while we use it; there is no safe way to do this yet.
|
||||||
Process* process = who ? Process::Get(who) : CurrentProcess();
|
Process* process = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcess();
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
ScopedLock lock(&process->nicelock);
|
ScopedLock lock(&process->nicelock);
|
||||||
|
@ -58,7 +59,7 @@ static int SetProcessPriority(pid_t who, int prio)
|
||||||
return errno = EINVAL, -1;
|
return errno = EINVAL, -1;
|
||||||
// TODO: If who isn't the current process, then it could self-destruct at
|
// TODO: If who isn't the current process, then it could self-destruct at
|
||||||
// any time while we use it; there is no safe way to do this yet.
|
// any time while we use it; there is no safe way to do this yet.
|
||||||
Process* process = who ? Process::Get(who) : CurrentProcess();
|
Process* process = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcess();
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
ScopedLock lock(&process->nicelock);
|
ScopedLock lock(&process->nicelock);
|
||||||
|
@ -81,7 +82,7 @@ static int GetProcessGroupPriority(pid_t who)
|
||||||
return errno = EINVAL, -1;
|
return errno = EINVAL, -1;
|
||||||
// TODO: If who isn't the current process, then it could self-destruct at
|
// TODO: If who isn't the current process, then it could self-destruct at
|
||||||
// any time while we use it; there is no safe way to do this yet.
|
// any time while we use it; there is no safe way to do this yet.
|
||||||
Process* group = who ? Process::Get(who) : CurrentProcessGroup();
|
Process* group = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcessGroup();
|
||||||
if ( !group )
|
if ( !group )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
int lowest = INT_MAX;
|
int lowest = INT_MAX;
|
||||||
|
@ -101,7 +102,7 @@ static int SetProcessGroupPriority(pid_t who, int prio)
|
||||||
return errno = EINVAL, -1;
|
return errno = EINVAL, -1;
|
||||||
// TODO: If who isn't the current process, then it could self-destruct at
|
// TODO: If who isn't the current process, then it could self-destruct at
|
||||||
// any time while we use it; there is no safe way to do this yet.
|
// any time while we use it; there is no safe way to do this yet.
|
||||||
Process* group = who ? Process::Get(who) : CurrentProcessGroup();
|
Process* group = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcessGroup();
|
||||||
if ( !group )
|
if ( !group )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
ScopedLock group_parent_lock(&group->groupparentlock);
|
ScopedLock group_parent_lock(&group->groupparentlock);
|
||||||
|
@ -161,7 +162,7 @@ int sys_prlimit(pid_t pid,
|
||||||
return errno = EINVAL, -1;
|
return errno = EINVAL, -1;
|
||||||
// TODO: If pid isn't the current process, then it could self-destruct at
|
// TODO: If pid isn't the current process, then it could self-destruct at
|
||||||
// any time while we use it; there is no safe way to do this yet.
|
// any time while we use it; there is no safe way to do this yet.
|
||||||
Process* process = pid ? Process::Get(pid) : CurrentProcess();
|
Process* process = pid ? CurrentProcess()->GetPTable()->Get(pid) : CurrentProcess();
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
ScopedLock lock(&process->resource_limits_lock);
|
ScopedLock lock(&process->resource_limits_lock);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <sortix/kernel/interrupt.h>
|
#include <sortix/kernel/interrupt.h>
|
||||||
#include <sortix/kernel/kernel.h>
|
#include <sortix/kernel/kernel.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/ptable.h>
|
||||||
#include <sortix/kernel/signal.h>
|
#include <sortix/kernel/signal.h>
|
||||||
#include <sortix/kernel/syscall.h>
|
#include <sortix/kernel/syscall.h>
|
||||||
#include <sortix/kernel/thread.h>
|
#include <sortix/kernel/thread.h>
|
||||||
|
@ -277,7 +278,7 @@ static int sys_kill(pid_t pid, int signum)
|
||||||
bool process_group = pid < 0 ? (pid = -pid, true) : false;
|
bool process_group = pid < 0 ? (pid = -pid, true) : false;
|
||||||
|
|
||||||
// TODO: Race condition: The process could be deleted while we use it.
|
// TODO: Race condition: The process could be deleted while we use it.
|
||||||
Process* process = Process::Get(pid);
|
Process* process = CurrentProcess()->GetPTable()->Get(pid);
|
||||||
if ( !process )
|
if ( !process )
|
||||||
return errno = ESRCH, -1;
|
return errno = ESRCH, -1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue