Skip to content

Commit

Permalink
Kernel: Changes in the way thread ids are handled
Browse files Browse the repository at this point in the history
  • Loading branch information
fido2020 committed Jul 12, 2021
1 parent cb36090 commit 83bf1bf
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 34 deletions.
24 changes: 17 additions & 7 deletions Applications/Terminal/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sys/wait.h>

#include <vector>
#include <mutex>

#include "escape.h"
#include "colours.h"
Expand All @@ -34,6 +35,8 @@ Lemon::GUI::Window* window;
bool paint = true;
bool paintAll = true;

std::mutex paintLock;

struct TermState{
bool bold : 1;
bool italic : 1;
Expand Down Expand Up @@ -523,16 +526,20 @@ void PrintChar(char ch){
while(waitpid(lsh, nullptr, WNOHANG) <= 0){
poll(fds.data(), fds.size(), 500000); // Wake up every 500ms to check if LSh has exited

bool needsPaint = false;
while(int len = read(masterPTYFd, buf, 512)){
for(int i = 0; i < len; i++){
PrintChar(buf[i]);
}

paint = true;
needsPaint = true;
}

if(paint){
Lemon::InterruptThread(0);
if(needsPaint){
std::lock_guard acquired(paintLock);

paint = true;
Lemon::InterruptThread(1);
}
}

Expand Down Expand Up @@ -635,11 +642,14 @@ int main(int argc, char** argv){
}
}

if(paint || paintAll){
window->Paint();
{
std::lock_guard acquired(paintLock);
if(paint){
window->Paint();

paint = false;
paintAll = false;
paint = false;
paintAll = false;
}
}

Lemon::WindowServer::Instance()->Wait();
Expand Down
18 changes: 15 additions & 3 deletions Kernel/include/Arch/x86_64/Scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ namespace Scheduler{
typedef struct Process {
pid_t pid = -1; // PID
AddressSpace* addressSpace; // Pointer to page directory and tables
uint8_t state = ThreadStateRunning; // Process state
Vector<Thread*> threads;
uint32_t threadCount = 0; // Amount of threads

List<Thread*> threads;
int64_t nextThreadID = 1;

int32_t euid = 0; // Effective UID
int32_t uid = 0;
int32_t egid = 0; // Effective GID
Expand All @@ -57,6 +58,16 @@ typedef struct Process {

uintptr_t usedMemoryBlocks;

ALWAYS_INLINE Thread* GetThreadFromID(pid_t id){
for(Thread* t : threads){
if(t->tid == id){
return t;
}
}

return nullptr;
}

ALWAYS_INLINE int AllocateFileDescriptor(fs_fd_t* ptr){
ScopedSpinLock lockFds(fileDescriptorsLock);

Expand Down Expand Up @@ -124,6 +135,7 @@ typedef struct Process {

lock_t fileDescriptorsLock = 0;
Vector<fs_fd_t*> fileDescriptors;
private:
} process_t;

namespace Scheduler{
Expand Down
2 changes: 1 addition & 1 deletion Kernel/include/Arch/x86_64/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct Thread {

uint64_t fsBase = 0;

pid_t tid = 0;
pid_t tid = 1;

bool blockTimedOut = false;
ThreadBlocker* blocker = nullptr;
Expand Down
15 changes: 6 additions & 9 deletions Kernel/src/Arch/x86_64/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ namespace Scheduler{
proc->threads.clear();

proc->threads.add_back(new Thread);
proc->threadCount = 1;

memset(proc->threads[0], 0, sizeof(Thread));

Expand All @@ -197,6 +196,7 @@ namespace Scheduler{
// Create structure for the main thread
Thread* thread = proc->threads[0];

thread->tid = proc->nextThreadID++;
thread->stack = 0;
thread->priority = 1;
thread->timeSliceDefault = 1;
Expand Down Expand Up @@ -250,7 +250,7 @@ namespace Scheduler{
process_t* proc = InitializeProcessStructure();
proc->addressSpace = new AddressSpace(Memory::CreatePageMap());

Thread* thread = proc->threads[0];
Thread* thread = proc->threads.get_front();

void* stack = (void*)Memory::KernelAllocate4KPages(32);
for(int i = 0; i < 32; i++){
Expand All @@ -263,7 +263,7 @@ namespace Scheduler{
thread->registers.rbp = (uintptr_t)thread->stack + PAGE_SIZE_4K * 32;
thread->registers.rip = (uintptr_t)entry;

InsertNewThreadIntoQueue(proc->threads[0]);
InsertNewThreadIntoQueue(proc->threads.get_front());

processes->add_back(proc);

Expand All @@ -289,10 +289,8 @@ namespace Scheduler{
}

pid_t CreateChildThread(process_t* process, uintptr_t entry, uintptr_t stack, uint64_t cs, uint64_t ss){
pid_t threadID = process->threadCount++;
process->threads.add_back(new Thread);

Thread& thread = *process->threads[threadID];
pid_t threadID = process->nextThreadID++;
Thread& thread = *process->threads.add_back(new Thread);

thread.tid = threadID;

Expand Down Expand Up @@ -345,8 +343,7 @@ namespace Scheduler{

CPU* cpu = GetCPULocal();
List<Thread*> runningThreads;
for(unsigned i = 0; i < process->threads.get_length(); i++){
Thread* thread = process->threads[i];
for(Thread* thread : process->threads){
if(thread != cpu->currentThread && thread){
if(thread->blocker && thread->state == ThreadStateBlocked){
thread->blocker->Interrupt(); // Stop the thread from blocking
Expand Down
52 changes: 38 additions & 14 deletions Kernel/src/Arch/x86_64/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#define SC_ARG4(r) (r)->r9
#define SC_ARG5(r) (r)->r8

#define NUM_SYSCALLS 101
#define NUM_SYSCALLS 102

#define EXEC_CHILD 1

Expand Down Expand Up @@ -585,6 +585,15 @@ long SysMapFB(RegisterContext *r){
return 0;
}

/////////////////////////////
/// \name SysGetTID - Get thread ID
///
/// \return Current thread's ID
/////////////////////////////
long SysGetTID(RegisterContext* r){
return Scheduler::GetCurrentThread()->tid;
}

long SysChmod(RegisterContext* r){
Process* proc = Scheduler::GetCurrentProcess();

Expand Down Expand Up @@ -1976,12 +1985,12 @@ long SysGetProcessInfo(RegisterContext* r){

pInfo->pid = pid;

pInfo->threadCount = reqProcess->threadCount;
pInfo->threadCount = reqProcess->threads.get_length();

pInfo->uid = reqProcess->uid;
pInfo->gid = reqProcess->gid;

pInfo->state = reqProcess->state;
pInfo->state = reqProcess->threads.get_front()->state;

strcpy(pInfo->name, reqProcess->name);

Expand Down Expand Up @@ -2029,12 +2038,12 @@ long SysGetNextProcessInfo(RegisterContext* r){

pInfo->pid = *pidP;

pInfo->threadCount = reqProcess->threadCount;
pInfo->threadCount = reqProcess->threads.get_length();

pInfo->uid = reqProcess->uid;
pInfo->gid = reqProcess->gid;

pInfo->state = reqProcess->state;
pInfo->state = reqProcess->threads.get_front()->state;

strcpy(pInfo->name, reqProcess->name);

Expand Down Expand Up @@ -3057,11 +3066,7 @@ long SysInterruptThread(RegisterContext* r){

long tid = SC_ARG0(r);

if(tid < 0 || tid > process->threads.get_length()){
return -EINVAL; // Thread does not exist
}

Thread* th = process->threads.get_at(tid);
Thread* th = process->GetThreadFromID(tid);
if(!th){
return -ESRCH; // Thread has already been killed
}
Expand Down Expand Up @@ -3150,7 +3155,7 @@ long SysFork(RegisterContext* r){
Thread* currentThread = Scheduler::GetCurrentThread();

Process* newProcess = Scheduler::CloneProcess(process);
Thread* thread = newProcess->threads[0];
Thread* thread = newProcess->threads.get_front();
void* threadKStack = thread->kernelStack; // Save the allocated kernel stack

*thread = *currentThread;
Expand All @@ -3162,7 +3167,7 @@ long SysFork(RegisterContext* r){
thread->lock = 0;
thread->stateLock = 0;

thread->tid = 0;
thread->tid = 1;

thread->blocker = nullptr;
thread->blockTimedOut = false;
Expand Down Expand Up @@ -3349,7 +3354,7 @@ long SysSocketPair(RegisterContext* r){
///
/// Returns the address of the peer connected to the socket \a sockfd in \a addr
/// The \a addrlen argument should indicate the amount of space pointed to by \a addr.
/// On return it will contian the size of the name
/// On return it will contain the size of the name
/// The address will be truncated if the addr buffer is too small
///
/// \param sockfd File descriptor of socket
Expand All @@ -3362,6 +3367,24 @@ long SysPeername(RegisterContext* r){
return -ENOSYS;
}

/////////////////////////////
/// \brief SysPeername(int sockfd, struct sockaddr* addr, socklen_t* addrlen) - get name of peer socket
///
/// Returns the address that the socket is bound to
/// The \a addrlen argument should indicate the amount of space pointed to by \a addr.
/// On return it will contain the size of the name
/// The address will be truncated if the addr buffer is too small
///
/// \param sockfd File descriptor of socket
/// \param addr Address buffer
/// \param addrlen
///
/// \return Negative error code on failure, otherwise 0
/////////////////////////////
long SysSockname(RegisterContext* r){
return -ENOSYS;
}

syscall_t syscalls[NUM_SYSCALLS]{
SysDebug,
SysExit, // 1
Expand All @@ -3378,7 +3401,7 @@ syscall_t syscalls[NUM_SYSCALLS]{
SysChdir,
SysTime,
SysMapFB,
nullptr, // 15
SysGetTID, // 15
SysChmod,
SysFStat,
SysStat,
Expand Down Expand Up @@ -3464,6 +3487,7 @@ syscall_t syscalls[NUM_SYSCALLS]{
SysGetEntropy,
SysSocketPair,
SysPeername, // 100
SysSockname,
};

void DumpLastSyscall(Thread* t){
Expand Down
2 changes: 2 additions & 0 deletions LibLemon/include/Lemon/System/ABI/Syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define SYS_CHDIR 12
#define SYS_TIME 13
#define SYS_MAP_FB 14
#define SYS_GETTID 15
#define SYS_CHMOD 16
#define SYS_FSTAT 17
#define SYS_STAT 18
Expand Down Expand Up @@ -98,3 +99,4 @@
#define SYS_GETENTROPY 98
#define SYS_SOCKETPAIR 99
#define SYS_PEERNAME 100
#define SYS_SOCKNAME 101

0 comments on commit 83bf1bf

Please sign in to comment.