mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-24 03:20:30 +00:00
Make improvements
- Introduce portable sched_getcpu() api - Support GCC's __target_clones__ feature - Make fma() go faster on x86 in default mode - Remove some asan checks from core libraries - WinMain() now ensures $HOME and $USER are defined
This commit is contained in:
parent
d5225a693b
commit
2ab9e9f7fd
192 changed files with 2809 additions and 932 deletions
|
@ -41,6 +41,7 @@ LIBC_CALLS_A_DIRECTDEPS = \
|
|||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_BCRYPTPRIMITIVES \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
|
@ -132,7 +133,8 @@ endif
|
|||
o/$(MODE)/libc/calls/pledge-linux.o: private \
|
||||
CFLAGS += \
|
||||
-Os \
|
||||
-fPIC
|
||||
-fPIC \
|
||||
-ffreestanding
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S
|
||||
|
|
|
@ -247,6 +247,8 @@ ssize_t tinyprint(int, const char *, ...) libcesque nullterminated();
|
|||
void shm_path_np(const char *, char[hasatleast 78]) libcesque;
|
||||
#endif /* _COSMO_SOURCE */
|
||||
|
||||
int system(const char *) libcesque;
|
||||
|
||||
int __wifstopped(int) libcesque pureconst;
|
||||
int __wifcontinued(int) libcesque pureconst;
|
||||
int __wifsignaled(int) libcesque pureconst;
|
||||
|
|
|
@ -21,12 +21,17 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/wintime.internal.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/nt/thread.h"
|
||||
|
||||
#define _CLOCK_REALTIME 0
|
||||
#define _CLOCK_MONOTONIC 1
|
||||
#define _CLOCK_REALTIME_COARSE 2
|
||||
#define _CLOCK_BOOTTIME 3
|
||||
#define _CLOCK_REALTIME 0
|
||||
#define _CLOCK_MONOTONIC 1
|
||||
#define _CLOCK_REALTIME_COARSE 2
|
||||
#define _CLOCK_BOOTTIME 3
|
||||
#define _CLOCK_PROCESS_CPUTIME_ID 4
|
||||
#define _CLOCK_THREAD_CPUTIME_ID 5
|
||||
|
||||
static struct {
|
||||
uint64_t base;
|
||||
|
@ -35,7 +40,7 @@ static struct {
|
|||
|
||||
textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
|
||||
uint64_t t;
|
||||
struct NtFileTime ft;
|
||||
struct NtFileTime ft, ftExit, ftUser, ftKernel, ftCreation;
|
||||
switch (clock) {
|
||||
case _CLOCK_REALTIME:
|
||||
if (ts) {
|
||||
|
@ -61,6 +66,22 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
|
|||
*ts = timespec_frommillis(GetTickCount64());
|
||||
}
|
||||
return 0;
|
||||
case _CLOCK_PROCESS_CPUTIME_ID:
|
||||
if (ts) {
|
||||
GetProcessTimes(GetCurrentProcess(), &ftCreation, &ftExit, &ftKernel,
|
||||
&ftUser);
|
||||
*ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) +
|
||||
ReadFileTime(ftKernel));
|
||||
}
|
||||
return 0;
|
||||
case _CLOCK_THREAD_CPUTIME_ID:
|
||||
if (ts) {
|
||||
GetThreadTimes(GetCurrentThread(), &ftCreation, &ftExit, &ftKernel,
|
||||
&ftUser);
|
||||
*ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) +
|
||||
ReadFileTime(ftKernel));
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -61,24 +61,13 @@ static int __clock_gettime_init(int clockid, struct timespec *ts) {
|
|||
/**
|
||||
* Returns nanosecond time.
|
||||
*
|
||||
* @param clock can be one of:
|
||||
* - `CLOCK_REALTIME`: universally supported
|
||||
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd
|
||||
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+
|
||||
* - `CLOCK_MONOTONIC`: universally supported (except on XNU/NT w/o INVTSC)
|
||||
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd
|
||||
* - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+
|
||||
* - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+
|
||||
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd PID)
|
||||
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd TID)
|
||||
* - `CLOCK_MONOTONIC_COARSE`: linux, freebsd
|
||||
* - `CLOCK_PROF`: linux and netbsd
|
||||
* - `CLOCK_BOOTTIME`: linux and openbsd
|
||||
* - `CLOCK_REALTIME_ALARM`: linux-only
|
||||
* - `CLOCK_BOOTTIME_ALARM`: linux-only
|
||||
* - `CLOCK_TAI`: linux-only
|
||||
* @param clock supports the following values across OSes:
|
||||
* - `CLOCK_REALTIME`
|
||||
* - `CLOCK_MONOTONIC`
|
||||
* - `CLOCK_REALTIME_COARSE`
|
||||
* - `CLOCK_MONOTONIC_COARSE`
|
||||
* - `CLOCK_THREAD_CPUTIME_ID`
|
||||
* - `CLOCK_PROCESS_CPUTIME_ID`
|
||||
* @param ts is where the result is stored (or null to do clock check)
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise EFAULT if `ts` points to invalid memory
|
||||
|
|
|
@ -93,7 +93,7 @@ static int close_impl(int fd) {
|
|||
*/
|
||||
int close(int fd) {
|
||||
int rc;
|
||||
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
|
||||
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
|
||||
BLOCK_SIGNALS;
|
||||
__fds_lock();
|
||||
rc = close_impl(fd);
|
||||
|
|
|
@ -103,7 +103,7 @@ static ssize_t GetDevUrandom(char *p, size_t n) {
|
|||
ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
||||
ssize_t rc;
|
||||
if (IsWindows()) {
|
||||
rc = RtlGenRandom(p, n) ? n : __winerr();
|
||||
rc = ProcessPrng(p, n) ? n : __winerr();
|
||||
} else if (have_getrandom) {
|
||||
if (IsXnu() || IsOpenbsd()) {
|
||||
rc = GetRandomBsd(p, n, GetRandomEntropy);
|
||||
|
@ -131,7 +131,7 @@ ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
|||
*
|
||||
* This random number seed generator obtains information from:
|
||||
*
|
||||
* - RtlGenRandom() on Windows
|
||||
* - ProcessPrng() on Windows
|
||||
* - getentropy() on XNU and OpenBSD
|
||||
* - getrandom() on Linux, FreeBSD, and NetBSD
|
||||
* - sysctl(KERN_ARND) on older versions of FreeBSD and NetBSD
|
||||
|
|
|
@ -75,7 +75,9 @@ textstartup void InitializeMetalFile(void) {
|
|||
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
|
||||
__ape_com_base = copied_base;
|
||||
__ape_com_size = size;
|
||||
KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size);
|
||||
// TODO(tkchia): LIBC_CALLS doesn't depend on LIBC_VGA so references
|
||||
// to its functions need to be weak
|
||||
// KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ static dontinline uint64_t rdrand_failover(void) {
|
|||
*
|
||||
* If RDRAND isn't available (we check CPUID and we also disable it
|
||||
* automatically for microarchitectures where it's slow or buggy) then
|
||||
* we try getrandom(), RtlGenRandom(), or sysctl(KERN_ARND). If those
|
||||
* we try getrandom(), ProcessPrng(), or sysctl(KERN_ARND). If those
|
||||
* aren't available then we try /dev/urandom and if that fails, we try
|
||||
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
|
||||
*
|
||||
|
|
|
@ -157,6 +157,8 @@ static textwindows struct Keystroke *NewKeystroke(void) {
|
|||
struct Keystroke *k = KEYSTROKE_CONTAINER(e);
|
||||
dll_remove(&__keystroke.free, &k->elem);
|
||||
--__keystroke.freekeys;
|
||||
// TODO(jart): What's wrong with GCC 12.3?
|
||||
asm("" : "+r"(k));
|
||||
k->buflen = 0;
|
||||
return k;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,19 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/cpuset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nexgen32e/rdtscp.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nt/struct/processornumber.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache);
|
||||
|
||||
/**
|
||||
* Returns ID of CPU on which thread is currently scheduled.
|
||||
* @return cpu number on success, or -1 w/ errno
|
||||
*/
|
||||
int sched_getcpu(void) {
|
||||
if (X86_HAVE(RDTSCP)) {
|
||||
|
@ -38,6 +42,19 @@ int sched_getcpu(void) {
|
|||
struct NtProcessorNumber pn;
|
||||
GetCurrentProcessorNumberEx(&pn);
|
||||
return 64 * pn.Group + pn.Number;
|
||||
} else if (IsXnuSilicon()) {
|
||||
if (__syslib->__version >= 9) {
|
||||
size_t cpu;
|
||||
errno_t err = __syslib->__pthread_cpu_number_np(&cpu);
|
||||
if (!err) {
|
||||
return cpu;
|
||||
} else {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
} else {
|
||||
unsigned cpu = 0;
|
||||
int rc = sys_getcpu(&cpu, 0, 0);
|
||||
|
|
|
@ -441,8 +441,7 @@ textwindows void __sig_generate(int sig, int sic) {
|
|||
// to unblock our sig once the wait operation is completed; when
|
||||
// that's the case we can cancel the thread's i/o to deliver sig
|
||||
if (atomic_load_explicit(&pt->pt_blocker, memory_order_acquire) &&
|
||||
!(atomic_load_explicit(&pt->pt_blkmask, memory_order_relaxed) &
|
||||
(1ull << (sig - 1)))) {
|
||||
!(pt->pt_blkmask & (1ull << (sig - 1)))) {
|
||||
_pthread_ref(pt);
|
||||
mark = pt;
|
||||
break;
|
||||
|
|
|
@ -18,7 +18,7 @@ int sys_fcntl_nt_setfl(int, unsigned);
|
|||
int sys_pause_nt(void);
|
||||
int64_t __fix_enotdir(int64_t, char16_t *);
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *);
|
||||
int64_t __winerr(void) nocallback privileged;
|
||||
int64_t __winerr(void) dontcallback privileged;
|
||||
int64_t ntreturn(uint32_t);
|
||||
void *GetProcAddressModule(const char *, const char *);
|
||||
void WinMainForked(void);
|
||||
|
|
|
@ -130,7 +130,7 @@ typedef struct ucontext ucontext_t;
|
|||
int getcontext(ucontext_t *) dontthrow;
|
||||
int setcontext(const ucontext_t *) dontthrow;
|
||||
int swapcontext(ucontext_t *, const ucontext_t *) dontthrow returnstwice;
|
||||
void makecontext(ucontext_t *, void (*)(), int, ...) dontthrow nocallback;
|
||||
void makecontext(ucontext_t *, void *, int, ...) dontthrow dontcallback;
|
||||
void __sig_restore(const ucontext_t *) wontreturn;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -82,15 +82,27 @@ static textwindows void GetNtName(char *name, int kind) {
|
|||
}
|
||||
|
||||
static inline textwindows int GetNtMajorVersion(void) {
|
||||
#ifdef __x86_64__
|
||||
return NtGetPeb()->OSMajorVersion;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline textwindows int GetNtMinorVersion(void) {
|
||||
#ifdef __x86_64__
|
||||
return NtGetPeb()->OSMinorVersion;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline textwindows int GetNtBuildNumber(void) {
|
||||
#ifdef __x86_64__
|
||||
return NtGetPeb()->OSBuildNumber;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static textwindows void GetNtVersion(char *p) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue