Commit Graph
145 Commits
Author SHA1 Message Date
Bananymous 8cd9e6dfa8 Kernel: Keep track of thread user and system time separately 2026-08-19 21:32:36 +03:00
Bananymous fc40820150 Kernel/Userspace: Replace my custom SHM system with SysV shm
This allows xbanan to use shm!
2026-08-08 01:52:12 +03:00
Bananymous 2e8239fefa Kernel: Fix thread block timeout
I was comparint ms against ns making timeouts practically never wake up
:)
2026-07-20 06:58:30 +03:00
Bananymous 6d1696b77e Kernel: Don't allocate userspace stacks in Thread
Thread only cares about stack's vaddr and size. Stacks are now allocated
before creating the threads.
2026-07-02 20:02:24 +03:00
Bananymous f449ca8161 Kenrel: Separate pthread API from kernel API
It didn't really make sense for the syscalls to be named as the pthread
equivalents. Now the kernel just uses thread ids
2026-07-02 20:02:24 +03:00
Bananymous d241975ce1 Kernel: Remove SYS_SLEEP and cleanup SYS_NANOSLEEP
`sleep` is now implemented in terms of `nanosleep`. `nanosleep` is now
more precise and handles overflow when calculating wakeup time. I don't
think anything was depending on this, but I could see a program sleeping
for max time to block until signal.
2026-07-02 15:22:52 +03:00
Bananymous 20663b533b Kernel: Rework sleeping API
instead of sleep_{ns,ms} we now have sleep_{for,until}_{ns,ms}. This
makes code cleaner that just wants to sleep until some timestamp
2026-07-02 15:22:52 +03:00
Bananymous fc1a6cacdc Kernel: Optimize process stopping 2026-06-27 03:24:15 +03:00
Bananymous 16a442f473 Kernel: Fix Thread::will_exit_because_of_signal
I was not checking whether the signal handler has been overwritten to
ignore the signal leading to infinite busy loops :)
2026-05-26 03:31:20 +03:00
Bananymous becfa228fe Kernel: fix signal handler block mask restoration 2026-05-26 03:31:20 +03:00
DcraftBgandBananymous 718379ce3b Kernel: moved read/write_from_user out of Process 2026-05-20 17:52:19 +03:00
Bananymous fde085e04b Kernel: Pass current cpu index as a GDT limit
I had no idea LSL was an instruction. This cleans up code to get the
current cpu by a lot and does not require extra segment usage :D
2026-05-04 20:26:02 +03:00
Bananymous b74812d669 Kernel: Remove unnused features from VirtualRange
On-demand paging has not been used ever since I made userspace stack be
a normal MemoryRegion.
2026-04-21 19:58:09 +03:00
Bananymous d11160d2f7 Kernel: Fix si_addr reporting
Meaning of this is signal specific and not the instruction pointer
2026-04-11 03:30:52 +03:00
Bananymous 8ca3c5d778 Kernel: Clean up signal handling
We now appreciate sa_mask and SA_NODEFER and change the signal mask for
the duration of signal handler. This is done by making a sigprocmask
syscall at the end of the signal handler. Back-to-back signals will
still grow stack as original registers are popped AFTER the block mask
is updated. I guess this is why linux has sigreturn(?).
2026-04-05 02:25:59 +03:00
Bananymous df257755f7 Kernel: If userspace sets fs or gs, dont overwrite it
Current cpu index is stored at either segment. If userspace sets that
segment, kernel will not overwrite it on every reschedule. This is fine
as long as user program does not use anything that relies on it :)
2026-04-04 23:48:43 +03:00
Bananymous 9fce114e8e Kernel: Don't clone entire kernel stack on fork
We only need to copy area between [ret_sp, stack_end]. This range is
always very small compared to the whole stack (64 KiB).
2026-04-04 23:48:43 +03:00
Bananymous 9d83424346 Kernel: Remove unnecessary stack pointer loading
Any time I started a thread I was loading the stack pointer which is
already correctly passed :D
2026-04-04 23:48:43 +03:00
Bananymous a29681a524 Kernel: Fix signal generation
We need to have interrupts enabled when signal kills the process as
process does mutex locking. Also signals are now only checked when
returning to userspace in the same place where userspace segments are
loaded.
2026-04-04 23:48:43 +03:00
Bananymous 1143dc3cae Kernel: Rework syscall memory validation and locking
Process's memory regions are now behind an rwlock instead of using the
full process lock. This allows most pointer validations to not block as
write operations to memory regions are rare.

Thread's userspace stack is now part of process's memory regions. This
simplifies code that explicitly looped over threads to see if the
accessed address was inside a thread's stack.

Only drawback of this is that MemoryRegions don't support guard pages,
so userspace stackoverflow will be handeled as cleanly as it was prior
to this.

This patch also fixes some unnecessary locking of the process lock and
moves locking to the internal helper functions instead of asserting that
the lock is held. Also we now make sure loaded ELF regions are in sorted
order as we previously expected.
2026-01-16 16:09:38 +02:00
Bananymous 4af9699b22 Kernel: Only save/load sse state when it is used
There is no need to save and load sse state on every interrupt. Instead
we can use CR0.TS to make threads trigger an interrupt when they use sse
instructions. This can be used to only save and load sse state when
needed.

Processor now keeps track of its current "sse thread" and the scheduler
either enabled or disabled sse based on which thread it is starting up.
When a thread dies, it checks if it was the current sse thread to avoid
use after free bugs. When load balancing, processor has to save the
thread's sse state before sending it to a new processor (if it was the
current sse thread). This ensures thread's sse state will be correct
when the new processor ends up loading it.
2026-01-11 03:06:39 +02:00
Bananymous 35c97e2ff8 Kernel: optimize yielding
Doing a yield no longer raises a software interrupt. Instead it just
saves all the callee saved registers, ip, sp and return value. Because
yield is only called in the kernel, it can just restore registers and
jump to the target address. There is never a need to use iret :)
2026-01-11 01:31:09 +02:00
Bananymous 12489a4c6b Kernel: Fix 32 bit target compile and runtime
Apparently I have to reload stack in the fork trampoline. Not sure why
or why not on x86_64. Also sse builtins did not compile
2026-01-09 17:06:57 +02:00
Bananymous 74f70ae4bd Kernel/LibC: Use builtin functions over inline asm
Getting flags and saving/restoring sse state and reading TSC can be done
using compiler builtins
2026-01-09 15:39:19 +02:00
Bananymous a9ceab0415 Kernel: Use syscall/sysret for syscalls in x86_64 2026-01-09 15:18:58 +02:00
Bananymous 9eb3834ae5 Kernel: Add syscall-less clock_gettime
If the processor has invariant TSC it can be used to measure time. We
keep track of the last nanosecond and TSC values and offset them based
on the current TSC. This allows getting current time in userspace.

The implementation maps a single RO page to every processes' address
space. The page contains the TSC info which gets updated every 100 ms.
If the processor does not have invariant TSC, this page will not
indicate the capability for TSC based timing.

There was the problem about how does a processor know which cpu it is
running without doing syscall. TSC counters may or may not be
synchronized between cores, so we need a separate TSC info for each
processor. I ended up adding sequence of bytes 0..255 at the start of
the shared page. When a scheduler gets a new thread, it updates the
threads gs/fs segment to point to the byte corresponding to the current
cpu.

This TSC based timing is also used in kernel. With 64 bit HPET this
probably does not bring much of a benefit, but on PIT or 32 bit HPET
this removes the need to aquire a spinlock to get the current time.

This change does force the userspace to not use gs/fs themselves and
they are both now reserved. Other one is used for TLS (this can be
technically used if user does not call libc code) and the other for
the current processor index (cannot be used as kernel unconditionally
resets it after each load balance).

I was looking at how many times timer's current time was polled
(userspace and kernel combined). When idling in window manager, it was
around 8k times/s. When running doom it peaked at over 1 million times
per second when loading and settled at ~30k times/s.
2026-01-08 17:13:59 +02:00
Bananymous dc454b9a6a Kernel: Fix SA_RESETHAND handling order
if SA_RESETHAND was set, alt stack would not get used
2025-12-31 19:28:55 +02:00
Bananymous dd636ffcb2 Kernel: Add support for SA_SIGINFO 2025-11-17 05:26:07 +02:00
Bananymous 09175d1799 Kernel: Fix 32 bit target
Rewrite some assembly and add some required casts
2025-11-17 02:33:00 +02:00
Bananymous 89c0ff1a9d Kernel/LibC: Replace SYS_{GET,SET}_TLS with SYS_{SET,GET}_{FS,GS}BASE
This allows userspace to use both registers
2025-11-13 04:20:53 +02:00
Bananymous 791a541381 Kernel: Implement process stopping and continuing 2025-08-31 00:34:52 +03:00
Bananymous 948ef2c820 Kernel: Fix race condition when destroying threads 2025-08-28 15:55:40 +03:00
Bananymous 10bd24e585 Kernel: Fix signal delivery without an alternate stack
I had only tested that sigaltstack worked, so I didn't notice my normal
signals broke :D
2025-08-25 22:16:23 +03:00
Bananymous 0dfe0b7023 Kernel/LibC: Implement sigaltstack 2025-08-21 02:52:49 +03:00
Bananymous 247743ef9c Kernel/LibC: Implement sigsuspend 2025-08-20 20:14:54 +03:00
Bananymous 49122cf729 Kernel: Allow adding signals to thread that are blocked 2025-08-20 18:35:18 +03:00
Bananymous 32d7f429f8 Kernel: Fix default ignored signals
SIGWINCH and SIGCANCEL ended up interrupting functions even when they
were marked as SIG_DFL. Now resizing the userspace terminal emulator
does not get interrupted!
2025-08-19 16:23:30 +03:00
Bananymous 72f85dce2b Kernel: Make userspace stack on-demand allocated
Also bump the hardlimit of stack size from 512 KiB->32 MiB. This still
feels quite low but is much better than before :D
2025-08-07 16:43:05 +03:00
Bananymous f27823babe Kernel: Move stacks to the top of userspace address space 2025-08-05 03:09:24 +03:00
Bananymous a51b589bc9 Kernel: Allow any signal flags and support SA_RESETHAND 2025-08-05 03:09:24 +03:00
Bananymous 6084aae603 Kernel: Add guard pages to kernel and userspace stacks 2025-07-02 23:12:36 +03:00
Bananymous 8a0269d29e Kernel: Remove kernel processes
Kernel can just use raw threads, pretty muchs the only thing that
process provides is syscalls which kernel threads of course don't
need.

Also this makes init process have pid 1 :D
2025-07-02 01:54:03 +03:00
Bananymous 41e1819072 Kernel: Align argv and envp to pointer boundary
This bug was found with ubsan
2025-07-02 00:17:42 +03:00
Bananymous f73bb242f3 Kernel: Save fpu state and flags in signal handler
This was causing some weird crashes :D
2025-06-28 16:55:13 +03:00
Bananymous 9e895e5286 Kernel: Use fxsave64 and fxrstor64 on 64 bit target 2025-06-28 16:55:13 +03:00
Bananymous 05a727979a Kernel: Make sse initialization thread safe 2025-06-28 16:55:13 +03:00
Bananymous 83c0ef3514 Kernel: Implement CLOCK_{PROCESS,THREAD}_CPUTIME_ID 2025-06-28 16:55:13 +03:00
Bananymous ef76ffa1c1 Kernel: Remove unnecessary hack
This is no longer needed as thread unlocks its spinlock before calling
Process::exit() on terminating signal
2025-06-06 11:13:55 +03:00
Bananymous c6ded82406 Kernel: Fix a deadlock when thread is executing terminating signal 2025-06-06 06:52:27 +03:00
Bananymous eecdad50a6 Kernel: Fix most of mutex + block race conditions
All block functions now take an optional mutex parameter that is
atomically unlocked instead of having the user unlock it before hand.
This prevents a ton of race conditions everywhere in the code!
2025-06-06 03:59:22 +03:00