banan-os/userspace/libraries/LibC
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
..
arch LibC: Make x86_64 crt0 PIE compatible 2025-11-10 01:40:33 +02:00
arpa LibC: Add inet_pton for IPv4 addresses 2025-10-02 16:19:49 +03:00
include Kernel/LibInput: Rework Joystick handling 2026-01-07 19:01:07 +02:00
net LibC: Implement if_{,free}nameindex 2025-11-07 14:54:53 +02:00
netinet LibC: Add in6addr_{any,loopback} definitions 2025-07-31 22:47:40 +03:00
sys LibC: Add stubs that I have locally 2026-01-06 21:58:56 +02:00
CMakeLists.txt LibC: Add stubs for shm_* functions 2026-01-06 21:58:56 +02:00
assert.cpp BuildSystem: Move all userpace libraries under the userspace directory 2024-06-18 13:14:35 +03:00
complex.cpp LibC: Implement all functions from complex.h 2025-06-01 13:48:03 +03:00
ctype.cpp BuildSystem: Move all userpace libraries under the userspace directory 2024-06-18 13:14:35 +03:00
dirent.cpp LibC: Implement readdir_r and fix memory leak 2025-10-30 16:33:17 +02:00
dlfcn.cpp LibC: Define Dl_info_t and add stub for dladdr 2025-08-19 16:23:30 +03:00
endian.cpp LibC: Add endian.h 2025-06-17 13:15:42 +03:00
environ.cpp LibC: Fix enviroment variable allocation 2025-06-28 20:25:35 +03:00
errno.cpp LibC: Make _get_uthread a macro 2025-08-05 03:09:24 +03:00
fcntl.cpp Kernel/LibC: Take fcntl extra field as uintptr_t 2025-11-10 01:40:33 +02:00
fenv.cpp Kernel/userspace: rework floating point math 2024-11-03 20:28:15 +02:00
fnmatch.cpp LibC: Implement fnmatch 2025-08-10 19:57:31 +03:00
ftw.cpp LibC: Add stubs for some functions in {dlfcn,ftw,utime,wchar}.h 2024-08-09 17:01:41 +03:00
getopt.cpp LibC: Implement getopt_long{,_only} 2025-08-11 18:36:46 +03:00
glob.cpp LibC: Implement glob{,free} 2025-11-23 05:33:44 +02:00
grp.cpp Kernel/LibC: Implement {get,set,init}groups 2025-08-10 19:57:31 +03:00
icxxabi.cpp LibC: Make {,__cxa_}atexit thread safe 2025-08-05 03:09:24 +03:00
ifaddrs.cpp LibC: Add stubs for {get,free}ifaddrs 2025-08-07 02:50:24 +03:00
inttypes.cpp LibC: Implement strto{u,i}max() 2024-08-05 00:53:27 +03:00
langinfo.cpp LibC: Implement nl_langinfo 2025-04-19 20:02:01 +03:00
libgen.cpp LibC: Implement basename and dirname 2024-12-02 20:13:37 +02:00
libintl.cpp LibC: Add dummy libintl support 2025-07-22 13:26:53 +03:00
locale.cpp LibC: Don't define SCHAR_MAX in locale.c 2025-04-21 22:21:40 +03:00
malloc.cpp LibC: Implement aligned_malloc 2025-07-31 22:47:40 +03:00
math.cpp LibC: Implement nan{,f,l} as functions 2024-11-08 02:49:21 +02:00
netdb.cpp LibC: Add stubs that I have locally 2026-01-06 21:58:56 +02:00
poll.cpp LibC: Implement pthread cancelation 2025-06-01 13:48:03 +03:00
printf_impl.cpp LibC: Fix printf %c modifier for null byte 2025-05-28 03:10:01 +03:00
pthread.cpp Kernel/LibC: Replace SYS_{GET,SET}_TLS with SYS_{SET,GET}_{FS,GS}BASE 2025-11-13 04:20:53 +02:00
pwd.cpp LibC: Implement getpw{nam,uid}_r 2025-07-31 22:47:40 +03:00
regex.cpp LibC: Implement posix regex 2025-11-17 05:26:07 +02:00
scanf_impl.cpp LibC: Fix scanf %n modifier 2025-04-22 09:55:38 +03:00
sched.cpp LibC: Add sched_get_priority_{min,max} 2025-06-28 16:55:13 +03:00
semaphore.cpp LibC: Implement sem_timedwait 2026-01-06 21:58:56 +02:00
setjmp.cpp LibC: Fix sigsetjmp 2025-08-21 02:52:49 +03:00
signal.cpp Kernel/LibC: Implement sigaltstack 2025-08-21 02:52:49 +03:00
spawn.cpp LibC: Implement simple posix_spawn{,p} 2025-11-10 01:40:33 +02:00
stdio.cpp LibC: Add stubs that I have locally 2026-01-06 21:58:56 +02:00
stdlib.cpp LibC: Implement random and srandom 2026-01-06 21:58:56 +02:00
string.cpp LibC: Define ESHUTDOWN 2025-11-02 21:09:48 +02:00
strings.cpp LibC: Implement deprecated bcmp, bcopy, bzero 2025-06-28 20:25:35 +03:00
syslog.cpp LibC: Cleanup syslog output 2025-08-16 22:56:03 +03:00
termios.cpp LibC: Implement pthread cancelation 2025-06-01 13:48:03 +03:00
time.cpp Kernel: Add syscall-less clock_gettime 2026-01-08 17:13:59 +02:00
unistd.cpp Kernel: Add syscall-less clock_gettime 2026-01-08 17:13:59 +02:00
utime.cpp Kernel/LibC: Implement utime* family functions 2025-06-01 13:48:03 +03:00
wchar-stdio.cpp LibC: Add some missing wchar.h functions 2025-06-01 13:48:03 +03:00
wchar.cpp LibC: Add stubs that I have locally 2026-01-06 21:58:56 +02:00