Bring back gc() function

Renaming gc() to _gc() was a mistake since the better thing to do is put
it behind the _COSMO_SOURCE macro. We need this change because I haven't
wanted to use my amazing garbage collector ever since we renamed it. You
now need to define _COSMO_SOURCE yourself when using amalgamation header
and cosmocc users need to pass the -mcosmo flag to get the gc() function

Some other issues relating to cancelation have been fixed along the way.
We're also now putting cosmocc in a folder named `.cosmocc` so it can be
more safely excluded by grep --exclude-dir=.cosmocc --exclude-dir=o etc.
This commit is contained in:
Justine Tunney 2024-01-08 10:07:35 -08:00
parent 6cb0354e19
commit a4b455185b
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
280 changed files with 1362 additions and 1407 deletions

3
.gitignore vendored
View file

@ -1,8 +1,7 @@
# -*- conf -*- # -*- conf -*-
/o /o
/cosmocc /.cosmocc
/.prompt.jtlp
# TODO: Find some way to have Python write to o/ # TODO: Find some way to have Python write to o/
__pycache__ __pycache__

View file

@ -150,7 +150,7 @@ export MODE
export SOURCE_DATE_EPOCH export SOURCE_DATE_EPOCH
export TMPDIR export TMPDIR
COSMOCC = cosmocc/3.2 COSMOCC = .cosmocc/3.2
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo- TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e) DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e)
@ -543,9 +543,6 @@ o/cosmopolitan.h: o/cosmopolitan.h.txt \
$(wildcard libc/integral/*) \ $(wildcard libc/integral/*) \
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS)) \ $(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS)) \
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_INCS)) $(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_INCS))
@$(ECHO) '#ifndef __STRICT_ANSI__' >$@
@$(ECHO) '#define _COSMO_SOURCE' >>$@
@$(ECHO) '#endif' >>$@
@$(COMPILE) -AROLLUP -T$@ build/bootstrap/rollup.com @$< >>$@ @$(COMPILE) -AROLLUP -T$@ build/bootstrap/rollup.com @$< >>$@
o/cosmopolitan.html: private .UNSANDBOXED = 1 o/cosmopolitan.html: private .UNSANDBOXED = 1

View file

@ -146,8 +146,6 @@ DEFAULT_CFLAGS = \
-std=gnu2x -std=gnu2x
DEFAULT_CXXFLAGS = \ DEFAULT_CXXFLAGS = \
-fno-rtti \
-fno-exceptions \
-fuse-cxa-atexit \ -fuse-cxa-atexit \
-Wno-int-in-bool-context \ -Wno-int-in-bool-context \
-Wno-narrowing \ -Wno-narrowing \

View file

@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
fi fi
find_objdump() { find_objdump() {
if [ -x cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then if [ -x .cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=cosmocc/3.2/bin/$1-linux-cosmo-objdump OBJDUMP=.cosmocc/3.2/bin/$1-linux-cosmo-objdump
elif [ -x cosmocc/3.2/bin/$1-linux-musl-objdump ]; then elif [ -x .cosmocc/3.2/bin/$1-linux-musl-objdump ]; then
OBJDUMP=cosmocc/3.2/bin/$1-linux-musl-objdump OBJDUMP=.cosmocc/3.2/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump" OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump" OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump"
else else
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2 echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
exit 1 exit 1

View file

@ -27,7 +27,7 @@
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/math.h" #include "libc/math.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -18,7 +18,7 @@
*/ */
#include "dsp/tty/tty.h" #include "dsp/tty/tty.h"
#include "libc/mem/arraylist2.internal.h" #include "libc/mem/arraylist2.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/x/x.h" #include "libc/x/x.h"

View file

@ -25,7 +25,7 @@
#include "libc/calls/ucontext.h" #include "libc/calls/ucontext.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/fileno.h"

View file

@ -285,7 +285,7 @@ int main(int argc, char *argv[]) {
// print all the ips that 0.0.0.0 would bind // print all the ips that 0.0.0.0 would bind
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF) // Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
uint32_t *hostips; uint32_t *hostips;
for (hostips = _gc(GetHostIps()), i = 0; hostips[i]; ++i) { for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) {
kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24, kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24,
hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT); hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT);
} }
@ -339,7 +339,7 @@ int main(int argc, char *argv[]) {
unassert(!pthread_attr_setguardsize(&attr, pagesz)); unassert(!pthread_attr_setguardsize(&attr, pagesz));
unassert(!pthread_attr_setsigmask_np(&attr, &block)); unassert(!pthread_attr_setsigmask_np(&attr, &block));
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0)); unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0));
pthread_t *th = _gc(calloc(threads, sizeof(pthread_t))); pthread_t *th = gc(calloc(threads, sizeof(pthread_t)));
for (i = 0; i < threads; ++i) { for (i = 0; i < threads; ++i) {
int rc; int rc;
++a_workers; ++a_workers;

View file

@ -50,7 +50,7 @@ void List(const char *path) {
if (strcmp(path, ".") == 0) { if (strcmp(path, ".") == 0) {
vpath = ""; vpath = "";
} else if (!endswith(path, "/")) { } else if (!endswith(path, "/")) {
vpath = _gc(xasprintf("%s/", path)); vpath = gc(xasprintf("%s/", path));
} else { } else {
vpath = path; vpath = path;
} }

View file

@ -80,10 +80,10 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id", DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
st->st_gid, "flags", st->st_flags, "gen", st->st_gen, st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
"device id (if special)", st->st_rdev, "block size", st->st_blksize, "device id (if special)", st->st_rdev, "block size", st->st_blksize,
"access time", _gc(xiso8601(&st->st_atim)), "modified time", "access time", gc(xiso8601(&st->st_atim)), "modified time",
_gc(xiso8601(&st->st_mtim)), "c[omplicated]time", gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
_gc(xiso8601(&st->st_ctim)), "birthtime", gc(xiso8601(&st->st_ctim)), "birthtime",
_gc(xiso8601(&st->st_birthtim))); gc(xiso8601(&st->st_birthtim)));
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {

View file

@ -128,7 +128,7 @@
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/alg.h" #include "libc/mem/alg.h"
#include "libc/mem/alloca.h" #include "libc/mem/alloca.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/paths.h" #include "libc/paths.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"

View file

@ -88,12 +88,14 @@ static ssize_t GetDevUrandom(char *p, size_t n) {
int fd; int fd;
ssize_t rc; ssize_t rc;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
fd = sys_openat(AT_FDCWD, "/dev/urandom", O_RDONLY | O_CLOEXEC, 0); fd = sys_openat(AT_FDCWD, "/dev/urandom", O_RDONLY | O_CLOEXEC, 0);
if (fd != -1) { if (fd != -1) {
rc = sys_read(fd, p, n); rc = sys_read(fd, p, n);
} else { } else {
rc = -1; rc = -1;
} }
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
return rc; return rc;
} }

View file

@ -53,7 +53,7 @@ int _mkstemp(char *, int);
* On newer Linux only (c. 2013) it's possible to turn the anonymous * On newer Linux only (c. 2013) it's possible to turn the anonymous
* returned file back into a real file, by doing this: * returned file back into a real file, by doing this:
* *
* linkat(AT_FDCWD, _gc(xasprintf("/proc/self/fd/%d", fd)), * linkat(AT_FDCWD, gc(xasprintf("/proc/self/fd/%d", fd)),
* AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW) * AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW)
* *
* On the New Technology, temporary files created by this function * On the New Technology, temporary files created by this function

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/atomic.h" #include "libc/atomic.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
@ -798,6 +799,7 @@ static void *dlopen_silicon(const char *path, int mode) {
void *cosmo_dlopen(const char *path, int mode) { void *cosmo_dlopen(const char *path, int mode) {
void *res; void *res;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
if (IsWindows()) { if (IsWindows()) {
res = dlopen_nt(path, mode); res = dlopen_nt(path, mode);
} else if (IsXnuSilicon()) { } else if (IsXnuSilicon()) {
@ -814,6 +816,7 @@ void *cosmo_dlopen(const char *path, int mode) {
} else { } else {
res = 0; res = 0;
} }
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
STRACE("dlopen(%#s, %d) → %p% m", path, mode, res); STRACE("dlopen(%#s, %d) → %p% m", path, mode, res);
return res; return res;

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dce.h"
#include "libc/intrin/describebacktrace.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h" #include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
@ -27,3 +29,14 @@ dontinstrument void __stracef(const char *fmt, ...) {
kvprintf(fmt, v); kvprintf(fmt, v);
va_end(v); va_end(v);
} }
#if IsModeDbg()
void report_cancellation_point(void) {
kprintf("error: cancelable raw system call not annotated in wrapper\n"
"choice #1 use BLOCK_CANCELATION / ALLOW_CANCELATION\n"
"choice #2 use BEGIN_CANCELATION_POINT / END_CANCELATION_POINT\n"
"backtrace: %s\n",
DescribeBacktrace(__builtin_frame_address(0)));
__builtin_trap();
}
#endif

View file

@ -3,19 +3,19 @@
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
__funline unsigned long __strlen(const char *s) { forceinline unsigned long __strlen(const char *s) {
unsigned long n = 0; unsigned long n = 0;
while (*s++) ++n; while (*s++) ++n;
return n; return n;
} }
__funline int __strcmp(const char *l, const char *r) { forceinline int __strcmp(const char *l, const char *r) {
size_t i = 0; size_t i = 0;
while (l[i] == r[i] && r[i]) ++i; while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 255) - (r[i] & 255); return (l[i] & 255) - (r[i] & 255);
} }
__funline char *__stpcpy(char *d, const char *s) { forceinline char *__stpcpy(char *d, const char *s) {
size_t i; size_t i;
for (i = 0;; ++i) { for (i = 0;; ++i) {
if (!(d[i] = s[i])) { if (!(d[i] = s[i])) {
@ -24,7 +24,7 @@ __funline char *__stpcpy(char *d, const char *s) {
} }
} }
__funline void *__repstosb(void *di, char al, size_t cx) { forceinline void *__repstosb(void *di, char al, size_t cx) {
#if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__) #if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm("rep stosb" asm("rep stosb"
: "=D"(di), "=c"(cx), "=m"(*(char(*)[cx])di) : "=D"(di), "=c"(cx), "=m"(*(char(*)[cx])di)
@ -40,7 +40,7 @@ __funline void *__repstosb(void *di, char al, size_t cx) {
#endif #endif
} }
__funline void *__repmovsb(void *di, const void *si, size_t cx) { forceinline void *__repmovsb(void *di, const void *si, size_t cx) {
#if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__) #if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm("rep movsb" asm("rep movsb"
: "=D"(di), "=S"(si), "=c"(cx), "=m"(*(char(*)[cx])di) : "=D"(di), "=S"(si), "=c"(cx), "=m"(*(char(*)[cx])di)
@ -57,7 +57,7 @@ __funline void *__repmovsb(void *di, const void *si, size_t cx) {
#endif #endif
} }
__funline void *__mempcpy(void *d, const void *s, size_t n) { forceinline void *__mempcpy(void *d, const void *s, size_t n) {
size_t i; size_t i;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
((char *)d)[i] = ((const char *)s)[i]; ((char *)d)[i] = ((const char *)s)[i];
@ -66,7 +66,7 @@ __funline void *__mempcpy(void *d, const void *s, size_t n) {
return (char *)d + n; return (char *)d + n;
} }
__funline char *__uintcpy(char p[hasatleast 21], uint64_t x) { forceinline char *__uintcpy(char p[hasatleast 21], uint64_t x) {
char t; char t;
size_t i, a, b; size_t i, a, b;
i = 0; i = 0;
@ -85,22 +85,22 @@ __funline char *__uintcpy(char p[hasatleast 21], uint64_t x) {
return p + i; return p + i;
} }
__funline char *__intcpy(char p[hasatleast 21], int64_t x) { forceinline char *__intcpy(char p[hasatleast 21], int64_t x) {
if (x < 0) *p++ = '-', x = -(uint64_t)x; if (x < 0) *p++ = '-', x = -(uint64_t)x;
return __uintcpy(p, x); return __uintcpy(p, x);
} }
__funline char *__fixcpy(char p[hasatleast 17], uint64_t x, uint8_t k) { forceinline char *__fixcpy(char p[hasatleast 17], uint64_t x, uint8_t k) {
while (k > 0) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15]; while (k > 0) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
*p = '\0'; *p = '\0';
return p; return p;
} }
__funline char *__hexcpy(char p[hasatleast 17], uint64_t x) { forceinline char *__hexcpy(char p[hasatleast 17], uint64_t x) {
return __fixcpy(p, x, ROUNDUP(x ? (__builtin_clzll(x) ^ 63) + 1 : 1, 4)); return __fixcpy(p, x, ROUNDUP(x ? (__builtin_clzll(x) ^ 63) + 1 : 1, 4));
} }
__funline const void *__memchr(const void *s, unsigned char c, size_t n) { forceinline const void *__memchr(const void *s, unsigned char c, size_t n) {
size_t i; size_t i;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if (((const unsigned char *)s)[i] == c) { if (((const unsigned char *)s)[i] == c) {
@ -110,7 +110,7 @@ __funline const void *__memchr(const void *s, unsigned char c, size_t n) {
return 0; return 0;
} }
__funline char *__strstr(const char *haystack, const char *needle) { forceinline char *__strstr(const char *haystack, const char *needle) {
size_t i; size_t i;
for (;;) { for (;;) {
for (i = 0;; ++i) { for (i = 0;; ++i) {
@ -123,8 +123,8 @@ __funline char *__strstr(const char *haystack, const char *needle) {
return 0; return 0;
} }
__funline char16_t *__strstr16(const char16_t *haystack, forceinline char16_t *__strstr16(const char16_t *haystack,
const char16_t *needle) { const char16_t *needle) {
size_t i; size_t i;
for (;;) { for (;;) {
for (i = 0;; ++i) { for (i = 0;; ++i) {
@ -137,21 +137,21 @@ __funline char16_t *__strstr16(const char16_t *haystack,
return 0; return 0;
} }
__funline const char *__strchr(const char *s, unsigned char c) { forceinline const char *__strchr(const char *s, unsigned char c) {
for (;; ++s) { for (;; ++s) {
if ((*s & 255) == c) return s; if ((*s & 255) == c) return s;
if (!*s) return 0; if (!*s) return 0;
} }
} }
__funline unsigned long __atoul(const char *p) { forceinline unsigned long __atoul(const char *p) {
int c; int c;
unsigned long x = 0; unsigned long x = 0;
while ('0' <= (c = *p++) && c <= '9') x *= 10, x += c - '0'; while ('0' <= (c = *p++) && c <= '9') x *= 10, x += c - '0';
return x; return x;
} }
__funline long __atol(const char *p) { forceinline long __atol(const char *p) {
int s = *p; int s = *p;
unsigned long x; unsigned long x;
if (s == '-' || s == '+') ++p; if (s == '-' || s == '+') ++p;
@ -160,7 +160,7 @@ __funline long __atol(const char *p) {
return x; return x;
} }
__funline void *__memset(void *a, int c, unsigned long n) { forceinline void *__memset(void *a, int c, unsigned long n) {
char *d = a; char *d = a;
unsigned long i; unsigned long i;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
@ -170,7 +170,7 @@ __funline void *__memset(void *a, int c, unsigned long n) {
return d; return d;
} }
__funline void *__memcpy(void *a, const void *b, unsigned long n) { forceinline void *__memcpy(void *a, const void *b, unsigned long n) {
char *d = a; char *d = a;
unsigned long i; unsigned long i;
const char *s = b; const char *s = b;
@ -181,7 +181,7 @@ __funline void *__memcpy(void *a, const void *b, unsigned long n) {
return d; return d;
} }
__funline void *__memmove(void *a, const void *b, unsigned long n) { forceinline void *__memmove(void *a, const void *b, unsigned long n) {
char *d = a; char *d = a;
unsigned long i; unsigned long i;
const char *s = b; const char *s = b;

View file

@ -95,6 +95,7 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f,
flockfile(f); flockfile(f);
strace_enabled(-1); strace_enabled(-1);
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
// We display TIMESTAMP.MICROS normally. However, when we log multiple // We display TIMESTAMP.MICROS normally. However, when we log multiple
// times in the same second, we display TIMESTAMP+DELTAMICROS instead. // times in the same second, we display TIMESTAMP+DELTAMICROS instead.
@ -136,6 +137,7 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f,
_Exit(22); _Exit(22);
} }
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
strace_enabled(+1); strace_enabled(+1);
funlockfile(f); funlockfile(f);

View file

@ -39,7 +39,7 @@ static void TeardownGc(void) {
if (__tls_enabled) { if (__tls_enabled) {
t = __get_tls(); t = __get_tls();
if ((g = t->tib_garbages)) { if ((g = t->tib_garbages)) {
// exit() currently doesn't use _gclongjmp() like pthread_exit() // exit() currently doesn't use gclongjmp() like pthread_exit()
// so we need to run the deferred functions manually. // so we need to run the deferred functions manually.
while (g->i) { while (g->i) {
--g->i; --g->i;
@ -88,7 +88,7 @@ static void DeferFunction(struct StackFrame *frame, void *fn, void *arg) {
frame->addr = (intptr_t)__gc; frame->addr = (intptr_t)__gc;
} }
// the gnu extension macros for _gc / _defer point here // the gnu extension macros for gc / defer point here
void __defer(void *rbp, void *fn, void *arg) { void __defer(void *rbp, void *fn, void *arg) {
struct StackFrame *f, *frame = rbp; struct StackFrame *f, *frame = rbp;
f = __builtin_frame_address(0); f = __builtin_frame_address(0);
@ -96,48 +96,3 @@ void __defer(void *rbp, void *fn, void *arg) {
unassert(PointerNotOwnedByParentStackFrame(f, frame, arg)); unassert(PointerNotOwnedByParentStackFrame(f, frame, arg));
DeferFunction(frame, fn, arg); DeferFunction(frame, fn, arg);
} }
/**
* Frees memory when function returns.
*
* This garbage collector overwrites the return address on the stack so
* that the RET instruction calls a trampoline which calls free(). It's
* loosely analogous to Go's defer keyword rather than a true cycle gc.
*
* const char *s = _gc(strdup("hello"));
* puts(s);
*
* This macro is equivalent to:
*
* _defer(free, ptr)
*
* @warning do not return a gc()'d pointer
* @warning do not realloc() with gc()'d pointer
* @warning be careful about static keyword due to impact of inlining
* @note you should use -fno-omit-frame-pointer
*/
void *(_gc)(void *thing) {
struct StackFrame *frame;
frame = __builtin_frame_address(0);
DeferFunction(frame->next, _weakfree, thing);
return thing;
}
/**
* Calls fn(arg) when function returns.
*
* This garbage collector overwrites the return address on the stack so
* that the RET instruction calls a trampoline which calls free(). It's
* loosely analogous to Go's defer keyword rather than a true cycle gc.
*
* @warning do not return a gc()'d pointer
* @warning do not realloc() with gc()'d pointer
* @warning be careful about static keyword due to impact of inlining
* @note you should use -fno-omit-frame-pointer
*/
void *(_defer)(void *fn, void *arg) {
struct StackFrame *frame;
frame = __builtin_frame_address(0);
DeferFunction(frame->next, fn, arg);
return arg;
}

View file

@ -1,25 +1,23 @@
#ifndef COSMOPOLITAN_LIBC_MEM_GC_H_ #ifndef COSMOPOLITAN_LIBC_MEM_GC_H_
#define COSMOPOLITAN_LIBC_MEM_GC_H_ #define COSMOPOLITAN_LIBC_MEM_GC_H_
#ifdef _COSMO_SOURCE
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
void *_gc(void *); void _gc_free(void *) libcesque;
void *_defer(void *, void *); void __defer(void *, void *, void *) libcesque;
void __defer(void *, void *, void *); void gclongjmp(void *, int) libcesque wontreturn;
void _gclongjmp(void *, int) dontthrow wontreturn; #define gc(THING) defer((void *)_gc_free, (void *)(THING))
void _gc_free(void *); #define _gc(THING) defer((void *)_gc_free, (void *)(THING))
#define defer(FN, ARG) \
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) ({ \
#define _gc(THING) _defer((void *)_gc_free, (void *)(THING)) autotype(ARG) Arg = (ARG); \
#define _defer(FN, ARG) \ /* prevent weird opts like tail call */ \
({ \ __asm__ volatile("" : "+g"(Arg) : : "memory"); \
autotype(ARG) Arg = (ARG); \ __defer(__builtin_frame_address(0), FN, Arg); \
/* prevent weird opts like tail call */ \ __asm__ volatile("" : "+g"(Arg) : : "memory"); \
asm volatile("" : "+g"(Arg) : : "memory"); \ Arg; \
__defer(__builtin_frame_address(0), FN, Arg); \
asm volatile("" : "+g"(Arg) : : "memory"); \
Arg; \
}) })
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* _COSMO_SOURCE */
#endif /* COSMOPOLITAN_LIBC_MEM_GC_H_ */ #endif /* COSMOPOLITAN_LIBC_MEM_GC_H_ */

View file

@ -1,9 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_MEM_GC_INTERNAL_H_
#define COSMOPOLITAN_LIBC_MEM_GC_INTERNAL_H_
#include "libc/mem/gc.h"
#define gc(THING) _gc(THING)
#define defer(FN, ARG) _defer(FN, ARG)
#define gclongjmp(JB, ARG) _gclongjmp(JB, ARG)
#endif /* COSMOPOLITAN_LIBC_MEM_GC_INTERNAL_H_ */

View file

@ -30,7 +30,7 @@
// @see examples/ctrlc.c // @see examples/ctrlc.c
// @noreturn // @noreturn
.ftrace1 .ftrace1
_gclongjmp: gclongjmp:
.ftrace2 .ftrace2
#ifdef __x86_64__ #ifdef __x86_64__
push %rbp push %rbp
@ -65,4 +65,4 @@ _gclongjmp:
#else #else
#error "unsupported architecture" #error "unsupported architecture"
#endif /* __x86_64__ */ #endif /* __x86_64__ */
.endfn _gclongjmp,globl .endfn gclongjmp,globl

View file

@ -23,7 +23,7 @@
// @param rdi points to the jmp_buf // @param rdi points to the jmp_buf
// @param esi is returned by setjmp() invocation (coerced nonzero) // @param esi is returned by setjmp() invocation (coerced nonzero)
// @noreturn // @noreturn
// @see _gclongjmp() // @see gclongjmp()
// @see siglongjmp() // @see siglongjmp()
.ftrace1 .ftrace1
longjmp: longjmp:

View file

@ -25,10 +25,11 @@
// @returnstwice // @returnstwice
// @assume system five nexgen32e abi conformant // @assume system five nexgen32e abi conformant
// @note code built w/ microsoft abi compiler can't call this // @note code built w/ microsoft abi compiler can't call this
// @see longjmp(), _gclongjmp() // @see longjmp(), gclongjmp()
.ftrace1 .ftrace1
setjmp: setjmp:
.ftrace2 .ftrace2
_setjmp:
#ifdef __x86_64__ #ifdef __x86_64__
lea 8(%rsp),%rax lea 8(%rsp),%rax
mov %rax,(%rdi) mov %rax,(%rdi)
@ -60,5 +61,5 @@ setjmp:
#else #else
#error "unsupported architecture" #error "unsupported architecture"
#endif #endif
.endfn _setjmp,globl
.endfn setjmp,globl .endfn setjmp,globl
.alias setjmp,_setjmp

View file

@ -58,6 +58,7 @@ static bool IsApeFile(const char *path) {
} else { } else {
bool res = false; bool res = false;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
int fd; int fd;
char buf[8]; char buf[8];
int flags = O_RDONLY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC; int flags = O_RDONLY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC;
@ -65,6 +66,7 @@ static bool IsApeFile(const char *path) {
res = sys_pread(fd, buf, 8, 0, 0) == 8 && IsApeLoadable(buf); res = sys_pread(fd, buf, 8, 0, 0) == 8 && IsApeLoadable(buf);
sys_close(fd); sys_close(fd);
} }
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
return res; return res;
} }

View file

@ -201,14 +201,14 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
} }
if (!__isfdkind(fd, kFdZip)) { if (!__isfdkind(fd, kFdZip)) {
bool memfdReq; bool memfdReq;
BEGIN_CANCELATION_POINT;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
strace_enabled(-1); strace_enabled(-1);
memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) && memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) &&
IsAPEFd(fd); IsAPEFd(fd);
strace_enabled(+1); strace_enabled(+1);
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
END_CANCELATION_POINT;
if (rc == -1) { if (rc == -1) {
break; break;
} else if (!memfdReq) { } else if (!memfdReq) {
@ -221,13 +221,13 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
} }
int newfd; int newfd;
char *path = alloca(PATH_MAX); char *path = alloca(PATH_MAX);
BEGIN_CANCELATION_POINT;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
strace_enabled(-1); strace_enabled(-1);
newfd = fd_to_mem_fd(fd, path); newfd = fd_to_mem_fd(fd, path);
strace_enabled(+1); strace_enabled(+1);
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
END_CANCELATION_POINT;
if (newfd == -1) { if (newfd == -1) {
break; break;
} }
@ -242,13 +242,13 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
if (!savedErr) { if (!savedErr) {
savedErr = errno; savedErr = errno;
} }
BEGIN_CANCELATION_POINT;
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
strace_enabled(-1); strace_enabled(-1);
close(newfd); close(newfd);
strace_enabled(+1); strace_enabled(+1);
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
END_CANCELATION_POINT;
} while (0); } while (0);
if (savedErr) { if (savedErr) {
errno = savedErr; errno = savedErr;

View file

@ -136,7 +136,7 @@ long __get_minsigstksz(void) pureconst;
void __get_main_stack(void **, size_t *, int *); void __get_main_stack(void **, size_t *, int *);
long __get_safe_size(long, long); long __get_safe_size(long, long);
char *__get_tmpdir(void); char *__get_tmpdir(void);
__funline int __trace_disabled(int x) { forceinline int __trace_disabled(int x) {
return 0; return 0;
} }
#ifndef FTRACE #ifndef FTRACE

View file

@ -96,7 +96,7 @@ extern char ape_stack_align[] __attribute__((__weak__));
* since it'll not only ensure stack overflows are detected, it * since it'll not only ensure stack overflows are detected, it
* will also trigger the stack to grow down safely. * will also trigger the stack to grow down safely.
*/ */
__funline void CheckLargeStackAllocation(void *p, ssize_t n) { forceinline void CheckLargeStackAllocation(void *p, ssize_t n) {
for (; n > 0; n -= 4096) { for (; n > 0; n -= 4096) {
((char *)p)[n - 1] = 0; ((char *)p)[n - 1] = 0;
} }

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
@ -45,7 +46,9 @@ int getentropy(void *p, size_t n) {
rc = 0; rc = 0;
} else { } else {
BLOCK_SIGNALS; BLOCK_SIGNALS;
BLOCK_CANCELATION;
if (__getrandom(p, n, 0) != n) notpossible; if (__getrandom(p, n, 0) != n) notpossible;
ALLOW_CANCELATION;
ALLOW_SIGNALS; ALLOW_SIGNALS;
rc = 0; rc = 0;
} }

View file

@ -42,7 +42,7 @@
* On newer Linux only (c. 2013) it's possible to turn the anonymous * On newer Linux only (c. 2013) it's possible to turn the anonymous
* returned file back into a real file, by doing this: * returned file back into a real file, by doing this:
* *
* linkat(AT_FDCWD, _gc(xasprintf("/proc/self/fd/%d", fileno(f))), * linkat(AT_FDCWD, gc(xasprintf("/proc/self/fd/%d", fileno(f))),
* AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW) * AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW)
* *
* On the New Technology, temporary files created by this function * On the New Technology, temporary files created by this function

View file

@ -116,11 +116,11 @@ void _pthread_unref(struct PosixThread *);
void _pthread_unwind(struct PosixThread *); void _pthread_unwind(struct PosixThread *);
void _pthread_zombify(struct PosixThread *); void _pthread_zombify(struct PosixThread *);
__funline pureconst struct PosixThread *_pthread_self(void) { forceinline pureconst struct PosixThread *_pthread_self(void) {
return (struct PosixThread *)__get_tls()->tib_pthread; return (struct PosixThread *)__get_tls()->tib_pthread;
} }
__funline void _pthread_ref(struct PosixThread *pt) { forceinline void _pthread_ref(struct PosixThread *pt) {
atomic_fetch_add_explicit(&pt->pt_refs, 1, memory_order_relaxed); atomic_fetch_add_explicit(&pt->pt_refs, 1, memory_order_relaxed);
} }

View file

@ -291,7 +291,7 @@ static errno_t _pthread_cancel_everyone(void) {
* Consider using Cosmopolitan Libc's garbage collector since it will be * Consider using Cosmopolitan Libc's garbage collector since it will be
* executed when a thread exits due to a cancelation. * executed when a thread exits due to a cancelation.
* *
* void *p = _gc(malloc(123)); * void *p = gc(malloc(123));
* read(0, p, 123); * read(0, p, 123);
* *
* It's possible to put a thread in asynchronous cancelation mode with * It's possible to put a thread in asynchronous cancelation mode with

View file

@ -84,8 +84,8 @@ void _pthread_unkey(struct CosmoTib *tib) {
* the callback function that was supplied to pthread_create(). This may * the callback function that was supplied to pthread_create(). This may
* be used if the thread wishes to exit at any other point in the thread * be used if the thread wishes to exit at any other point in the thread
* lifecycle, in which case this function is responsible for ensuring we * lifecycle, in which case this function is responsible for ensuring we
* invoke _gc(), _defer(), and pthread_cleanup_push() callbacks, as well * invoke gc(), _defer(), and pthread_cleanup_push() callbacks, and also
* as pthread_key_create() destructors. * pthread_key_create() destructors.
* *
* If the current thread is an orphaned thread, or is the main thread * If the current thread is an orphaned thread, or is the main thread
* when no other threads were created, then this will terminated your * when no other threads were created, then this will terminated your

View file

@ -65,7 +65,7 @@ void __set_tls(struct CosmoTib *);
* *
* This can't be used in privileged functions. * This can't be used in privileged functions.
*/ */
__funline pureconst struct CosmoTib *__get_tls(void) { forceinline pureconst struct CosmoTib *__get_tls(void) {
#ifdef __chibicc__ #ifdef __chibicc__
return 0; return 0;
#elif __x86_64__ #elif __x86_64__

View file

@ -11,7 +11,7 @@ COSMOPOLITAN_C_START_
* This should be favored over __get_tls() for .privileged code that * This should be favored over __get_tls() for .privileged code that
* can't be self-modified by __enable_tls(). * can't be self-modified by __enable_tls().
*/ */
__funline struct CosmoTib *__get_tls_privileged(void) { forceinline struct CosmoTib *__get_tls_privileged(void) {
char *tib, *lin = (char *)0x30; char *tib, *lin = (char *)0x30;
if (IsLinux() || IsFreebsd() || IsNetbsd() || IsOpenbsd() || IsMetal()) { if (IsLinux() || IsFreebsd() || IsNetbsd() || IsOpenbsd() || IsMetal()) {
if (!__tls_morphed) { if (!__tls_morphed) {
@ -28,14 +28,14 @@ __funline struct CosmoTib *__get_tls_privileged(void) {
return (struct CosmoTib *)tib; return (struct CosmoTib *)tib;
} }
__funline struct CosmoTib *__get_tls_win32(void) { forceinline struct CosmoTib *__get_tls_win32(void) {
char *tib, *lin = (char *)0x30; char *tib, *lin = (char *)0x30;
asm("mov\t%%gs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory"); asm("mov\t%%gs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory");
tib = *(char **)(tib + 0x1480 + __tls_index * 8); tib = *(char **)(tib + 0x1480 + __tls_index * 8);
return (struct CosmoTib *)tib; return (struct CosmoTib *)tib;
} }
__funline void __set_tls_win32(void *tls) { forceinline void __set_tls_win32(void *tls) {
asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tls)); asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tls));
} }

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/fmt/libgen.h" #include "libc/fmt/libgen.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/x/x.h" #include "libc/x/x.h"

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "net/https/https.h" #include "net/https/https.h"
bool ChainCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *parent) { bool ChainCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *parent) {

View file

@ -37,8 +37,8 @@ struct Cert FinishCertificate(struct Cert *ca, mbedtls_x509write_cert *wcert,
if ((rc = mbedtls_pk_check_pair(&cert->pk, key))) { if ((rc = mbedtls_pk_check_pair(&cert->pk, key))) {
FATALF("generate key (grep -0x%04x)", -rc); FATALF("generate key (grep -0x%04x)", -rc);
} }
LogCertificate(_gc(xasprintf("generated %s certificate", LogCertificate(
mbedtls_pk_get_name(&cert->pk))), gc(xasprintf("generated %s certificate", mbedtls_pk_get_name(&cert->pk))),
cert); cert);
return (struct Cert){cert, key}; return (struct Cert){cert, key};
} }

View file

@ -32,7 +32,6 @@
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
#include "libc/serialize.h"
#include "libc/intrin/bsr.h" #include "libc/intrin/bsr.h"
#include "libc/intrin/hilbert.h" #include "libc/intrin/hilbert.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
@ -49,6 +48,7 @@
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h" #include "libc/runtime/stack.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"
#include "libc/serialize.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
#include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/pollfd.h"
#include "libc/sock/struct/sockaddr.h" #include "libc/sock/struct/sockaddr.h"
@ -815,13 +815,13 @@ void *ListenWorker(void *arg) {
void *HttpWorker(void *arg) { void *HttpWorker(void *arg) {
struct Client client; struct Client client;
int id = (intptr_t)arg; int id = (intptr_t)arg;
char *msgbuf = _gc(xmalloc(MSG_BUF)); char *msgbuf = gc(xmalloc(MSG_BUF));
char *inbuf = NewSafeBuffer(INBUF_SIZE); char *inbuf = NewSafeBuffer(INBUF_SIZE);
char *outbuf = NewSafeBuffer(OUTBUF_SIZE); char *outbuf = NewSafeBuffer(OUTBUF_SIZE);
struct HttpMessage *msg = _gc(xcalloc(1, sizeof(struct HttpMessage))); struct HttpMessage *msg = gc(xcalloc(1, sizeof(struct HttpMessage)));
BlockSignals(); BlockSignals();
pthread_setname_np(pthread_self(), _gc(xasprintf("HTTP%d", id))); pthread_setname_np(pthread_self(), gc(xasprintf("HTTP%d", id)));
// connection loop // connection loop
while (GetClient(&g_clients, &client)) { while (GetClient(&g_clients, &client)) {
@ -1761,7 +1761,7 @@ void *ClaimWorker(void *arg) {
long processed; long processed;
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
bool warmedup = false; bool warmedup = false;
struct Claim *v = _gc(xcalloc(BATCH_MAX, sizeof(struct Claim))); struct Claim *v = gc(xcalloc(BATCH_MAX, sizeof(struct Claim)));
BlockSignals(); BlockSignals();
pthread_setname_np(pthread_self(), "ClaimWorker"); pthread_setname_np(pthread_self(), "ClaimWorker");
LOG("%P ClaimWorker started\n"); LOG("%P ClaimWorker started\n");

View file

@ -18,7 +18,7 @@
*/ */
#include "dsp/core/core.h" #include "dsp/core/core.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/hyperion.h" #include "libc/testlib/hyperion.h"

View file

@ -20,7 +20,7 @@
#include "dsp/core/q.h" #include "dsp/core/q.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -23,7 +23,7 @@
#include "libc/fmt/bing.internal.h" #include "libc/fmt/bing.internal.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/math.h" #include "libc/math.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -23,7 +23,7 @@
#include "dsp/core/half.h" #include "dsp/core/half.h"
#include "libc/fmt/bing.internal.h" #include "libc/fmt/bing.internal.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -20,7 +20,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/mem/alloca.h" #include "libc/mem/alloca.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/auxv.h"

View file

@ -25,7 +25,7 @@
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"

View file

@ -38,7 +38,7 @@ void SetUpOnce(void) {
void Make(const char *path, int mode) { void Make(const char *path, int mode) {
int fd, n = lemur64() & 0xfffff; int fd, n = lemur64() & 0xfffff;
char *data = _gc(malloc(n)); char *data = gc(malloc(n));
rngset(data, n, lemur64, -1); rngset(data, n, lemur64, -1);
ASSERT_NE(-1, (fd = creat(path, mode))); ASSERT_NE(-1, (fd = creat(path, mode)));
ASSERT_SYS(0, n, write(fd, data, n)); ASSERT_SYS(0, n, write(fd, data, n));
@ -77,8 +77,8 @@ TEST(copy_file_range, test) {
size_t n, m; size_t n, m;
Make("foo", 0644); Make("foo", 0644);
Copy("foo", "bar"); Copy("foo", "bar");
p = _gc(xslurp("foo", &n)); p = gc(xslurp("foo", &n));
q = _gc(xslurp("bar", &m)); q = gc(xslurp("bar", &m));
ASSERT_EQ(n, m); ASSERT_EQ(n, m);
ASSERT_EQ(0, memcmp(p, q, n)); ASSERT_EQ(0, memcmp(p, q, n));
} }

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -23,7 +23,7 @@
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/safemacros.internal.h" #include "libc/intrin/safemacros.internal.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/nexgen32e/vendor.internal.h" #include "libc/nexgen32e/vendor.internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -22,7 +22,7 @@
#include "libc/fmt/libgen.h" #include "libc/fmt/libgen.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/serialize.h" #include "libc/serialize.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -22,7 +22,6 @@
#include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/serialize.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/math.h" #include "libc/math.h"
@ -30,6 +29,7 @@
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/serialize.h"
#include "libc/stdio/lcg.internal.h" #include "libc/stdio/lcg.internal.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
@ -70,7 +70,7 @@ void *TortureWorker(void *arg) {
TEST(getrandom, test) { TEST(getrandom, test) {
int i, n = 999; int i, n = 999;
double e, w = 7.7; double e, w = 7.7;
char *buf = _gc(calloc(1, n)); char *buf = gc(calloc(1, n));
ASSERT_SYS(0, 0, getrandom(0, 0, 0)); ASSERT_SYS(0, 0, getrandom(0, 0, 0));
ASSERT_SYS(0, n, getrandom(buf, n, 0)); ASSERT_SYS(0, n, getrandom(buf, n, 0));
ASSERT_SYS(EFAULT, -1, getrandom(0, n, 0)); ASSERT_SYS(EFAULT, -1, getrandom(0, n, 0));
@ -92,7 +92,7 @@ TEST(getrandom, test2) {
double e, w = 7.7; double e, w = 7.7;
struct sigaction sa; struct sigaction sa;
int i, k, m, n = 999; int i, k, m, n = 999;
char *buf = _gc(calloc(1, n)); char *buf = gc(calloc(1, n));
sa.sa_flags = 0; sa.sa_flags = 0;
sa.sa_handler = OnSig; sa.sa_handler = OnSig;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);

View file

@ -20,7 +20,7 @@
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"

View file

@ -19,7 +19,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/thread/thread.h" #include "libc/thread/thread.h"

View file

@ -20,7 +20,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -18,7 +18,7 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/proc/ntspawn.h" #include "libc/proc/ntspawn.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/proc/ntspawn.h" #include "libc/proc/ntspawn.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -19,7 +19,7 @@
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#if SupportsWindows() #if SupportsWindows()

View file

@ -24,7 +24,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -21,7 +21,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"

View file

@ -96,7 +96,7 @@ TEST(poll, testNegativeOneFd_isIgnored) {
EXPECT_SYS(0, 0, poll(fds, ARRAYLEN(fds), 1)); EXPECT_SYS(0, 0, poll(fds, ARRAYLEN(fds), 1));
EXPECT_STREQ("fd:-1 revents:<TODO:kPollNames>\n" EXPECT_STREQ("fd:-1 revents:<TODO:kPollNames>\n"
"fd:3 revents:<TODO:kPollNames>\n", "fd:3 revents:<TODO:kPollNames>\n",
_gc(FormatPollFd(&fds[0]))); gc(FormatPollFd(&fds[0])));
ASSERT_SYS(0, 0, close(3)); ASSERT_SYS(0, 0, close(3));
} }

View file

@ -23,7 +23,7 @@
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/runtime/symbols.internal.h" #include "libc/runtime/symbols.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"

View file

@ -23,7 +23,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"

View file

@ -22,7 +22,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"

View file

@ -23,7 +23,7 @@
#include "libc/calls/ucontext.h" #include "libc/calls/ucontext.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"

View file

@ -23,7 +23,7 @@
#include "libc/calls/ucontext.h" #include "libc/calls/ucontext.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"

View file

@ -25,7 +25,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/nt/files.h" #include "libc/nt/files.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -23,7 +23,7 @@
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
@ -55,7 +55,7 @@ TEST(writev, negative_einvalOrEfault) {
TEST(writev, exceedsIovMax_einval) { TEST(writev, exceedsIovMax_einval) {
if (IsWindows()) return; // it's complicated if (IsWindows()) return; // it's complicated
int i, n = IOV_MAX + 1; int i, n = IOV_MAX + 1;
struct iovec *v = _gc(malloc(sizeof(struct iovec) * n)); struct iovec *v = gc(malloc(sizeof(struct iovec) * n));
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
v[i].iov_base = "x"; v[i].iov_base = "x";
v[i].iov_len = 1; v[i].iov_len = 1;

View file

@ -18,7 +18,7 @@
*/ */
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/libgen.h" #include "libc/fmt/libgen.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/x/x.h" #include "libc/x/x.h"

View file

@ -19,7 +19,7 @@
#include "libc/fmt/leb128.h" #include "libc/fmt/leb128.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
TEST(zleb64, testZero) { TEST(zleb64, testZero) {

View file

@ -20,7 +20,7 @@
#include "libc/cosmo.h" #include "libc/cosmo.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/thread/thread.h" #include "libc/thread/thread.h"

View file

@ -19,7 +19,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/intrin/popcnt.h" #include "libc/intrin/popcnt.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h" #include "libc/runtime/sysconf.h"

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/nexgen32e.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"

View file

@ -18,7 +18,7 @@
*/ */
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -21,7 +21,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -25,7 +25,7 @@
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/math.h" #include "libc/math.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"

View file

@ -19,7 +19,7 @@
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/cachesize.h" #include "libc/nexgen32e/cachesize.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"

View file

@ -115,7 +115,7 @@ TEST(ShowCrashReports, testMemoryLeakCrash) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
EXPECT_EQ(78 << 8, ws); EXPECT_EQ(78 << 8, ws);
ASSERT_TRUE(!!strstr(output, "UNFREED MEMORY")); ASSERT_TRUE(!!strstr(output, "UNFREED MEMORY"));
if (IsAsan()) { if (IsAsan()) {
@ -207,7 +207,7 @@ TEST(ShowCrashReports, testDivideByZero) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
if (IsModeDbg()) { if (IsModeDbg()) {
EXPECT_EQ(77 << 8, ws); EXPECT_EQ(77 << 8, ws);
} else { } else {
@ -222,32 +222,32 @@ TEST(ShowCrashReports, testDivideByZero) {
// UBSAN handled it // UBSAN handled it
} else { } else {
// ShowCrashReports() handled it // ShowCrashReports() handled it
if (!strstr(output, _gc(xasprintf("%d", pid)))) { if (!strstr(output, gc(xasprintf("%d", pid)))) {
fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
if (!strstr(output, "SIGFPE")) { if (!strstr(output, "SIGFPE")) {
fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n", fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
// XXX: WSL doesn't save and restore x87 registers to ucontext_t // XXX: WSL doesn't save and restore x87 registers to ucontext_t
if (!__iswsl1()) { if (!__iswsl1()) {
if (!strstr(output, "3.141")) { if (!strstr(output, "3.141")) {
fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n", fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
} }
if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) { if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) {
fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n", fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
if (!strstr(output, "3133731337")) { if (!strstr(output, "3133731337")) {
fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n", fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
} }
@ -332,7 +332,7 @@ TEST(ShowCrashReports, testBssOverrunCrash) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
EXPECT_EQ(77 << 8, ws); EXPECT_EQ(77 << 8, ws);
/* NULL is stopgap until we can copy symbol tablces into binary */ /* NULL is stopgap until we can copy symbol tablces into binary */
#ifdef __FNO_OMIT_FRAME_POINTER__ #ifdef __FNO_OMIT_FRAME_POINTER__
@ -407,7 +407,7 @@ TEST(ShowCrashReports, testNpeCrash) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
EXPECT_EQ(77 << 8, ws); EXPECT_EQ(77 << 8, ws);
/* NULL is stopgap until we can copy symbol tables into binary */ /* NULL is stopgap until we can copy symbol tables into binary */
ASSERT_TRUE(!!strstr(output, "null pointer")); ASSERT_TRUE(!!strstr(output, "null pointer"));
@ -451,7 +451,7 @@ TEST(ShowCrashReports, testDataOverrunCrash) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
EXPECT_EQ(77 << 8, ws); EXPECT_EQ(77 << 8, ws);
/* NULL is stopgap until we can copy symbol tablces into binary */ /* NULL is stopgap until we can copy symbol tablces into binary */
#ifdef __FNO_OMIT_FRAME_POINTER__ #ifdef __FNO_OMIT_FRAME_POINTER__
@ -499,7 +499,7 @@ TEST(ShowCrashReports, testNpeCrashAfterFinalize) {
} }
close(fds[0]); close(fds[0]);
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
// tinyprint(2, _gc(IndentLines(output, -1, 0, 4)), "\n", NULL); // tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
if (IsModeDbg()) { if (IsModeDbg()) {
EXPECT_EQ(77 << 8, ws); EXPECT_EQ(77 << 8, ws);
} else { } else {
@ -509,13 +509,13 @@ TEST(ShowCrashReports, testNpeCrashAfterFinalize) {
/* NULL is stopgap until we can copy symbol tables into binary */ /* NULL is stopgap until we can copy symbol tables into binary */
if (!strstr(output, IsAsan() ? "null pointer" : "Uncaught SIGSEGV (SEGV_")) { if (!strstr(output, IsAsan() ? "null pointer" : "Uncaught SIGSEGV (SEGV_")) {
fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
#ifdef __FNO_OMIT_FRAME_POINTER__ #ifdef __FNO_OMIT_FRAME_POINTER__
if (!OutputHasSymbol(output, "NpeCrash")) { if (!OutputHasSymbol(output, "NpeCrash")) {
fprintf(stderr, "ERROR: crash report didn't have backtrace\n%s\n", fprintf(stderr, "ERROR: crash report didn't have backtrace\n%s\n",
_gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
#endif #endif

View file

@ -54,9 +54,9 @@ void insertionsort(int32_t *a, size_t n) {
TEST(djbsort, test4) { TEST(djbsort, test4) {
static const int kA[] = {4, 3, 2, 1}; static const int kA[] = {4, 3, 2, 1};
n = ARRAYLEN(kA); n = ARRAYLEN(kA);
a = memcpy(_gc(malloc(n * 4)), kA, n * 4); a = memcpy(gc(malloc(n * 4)), kA, n * 4);
b = memcpy(_gc(malloc(n * 4)), kA, n * 4); b = memcpy(gc(malloc(n * 4)), kA, n * 4);
c = memcpy(_gc(malloc(n * 4)), kA, n * 4); c = memcpy(gc(malloc(n * 4)), kA, n * 4);
insertionsort(a, n); insertionsort(a, n);
djbsort_avx2(b, n); djbsort_avx2(b, n);
djbsort(c, n); djbsort(c, n);
@ -82,9 +82,9 @@ TEST(djbsort, test64) {
-1323943608, -1219421355, -582289873, 1062699814, -1323943608, -1219421355, -582289873, 1062699814,
}; };
n = ARRAYLEN(kA); n = ARRAYLEN(kA);
a = memcpy(_gc(malloc(n * 4)), kA, n * 4); a = memcpy(gc(malloc(n * 4)), kA, n * 4);
b = memcpy(_gc(malloc(n * 4)), kA, n * 4); b = memcpy(gc(malloc(n * 4)), kA, n * 4);
c = memcpy(_gc(malloc(n * 4)), kA, n * 4); c = memcpy(gc(malloc(n * 4)), kA, n * 4);
insertionsort(a, n); insertionsort(a, n);
djbsort(c, n); djbsort(c, n);
ASSERT_EQ(0, memcmp(a, c, n * 4)); ASSERT_EQ(0, memcmp(a, c, n * 4));
@ -104,7 +104,7 @@ static int CompareInt(const void *a, const void *b) {
BENCH(djbsort, bench) { BENCH(djbsort, bench) {
n = 256; n = 256;
a = _gc(memalign(32, n * 4)); a = gc(memalign(32, n * 4));
EZBENCH2("insertionsort[255]", rngset(a, n * 4, _rand64, -1), EZBENCH2("insertionsort[255]", rngset(a, n * 4, _rand64, -1),
insertionsort(a, n)); insertionsort(a, n));
EZBENCH2("djbsort[255]", rngset(a, n * 4, _rand64, -1), djbsort(a, n)); EZBENCH2("djbsort[255]", rngset(a, n * 4, _rand64, -1), djbsort(a, n));

View file

@ -26,7 +26,7 @@
#include "libc/intrin/safemacros.internal.h" #include "libc/intrin/safemacros.internal.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
@ -210,7 +210,7 @@ void *Worker(void *arg) {
BENCH(malloc, torture) { BENCH(malloc, torture) {
int i, n = __get_cpu_count() * 2; int i, n = __get_cpu_count() * 2;
pthread_t *t = _gc(malloc(sizeof(pthread_t) * n)); pthread_t *t = gc(malloc(sizeof(pthread_t) * n));
if (!n) return; if (!n) return;
printf("\nmalloc torture test w/ %d threads and %d iterations\n", n, printf("\nmalloc torture test w/ %d threads and %d iterations\n", n,
ITERATIONS); ITERATIONS);

View file

@ -19,7 +19,7 @@
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/alg.h" #include "libc/mem/alg.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"

View file

@ -19,7 +19,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -18,9 +18,7 @@
*/ */
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/gc.internal.h"
#include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/nexgen32e.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
@ -32,7 +30,7 @@
#ifdef __x86_64__ #ifdef __x86_64__
// TODO(jart): get gclongjmp() working properly on aarch64 // TODO(jart): get gclongjmp() working properly on aarch64
#define GC(x) _defer(Free, x) #define GC(x) defer(Free, x)
char *x; char *x;
char *y; char *y;
@ -83,7 +81,7 @@ TEST(gclongjmp, test) {
void crawl(const char *path) { void crawl(const char *path) {
if (!strcmp(path, "/") || !strcmp(path, ".")) return; if (!strcmp(path, "/") || !strcmp(path, ".")) return;
crawl(_gc(xdirname(path))); crawl(gc(xdirname(path)));
} }
void *Worker(void *arg) { void *Worker(void *arg) {
@ -99,8 +97,8 @@ TEST(gc, torture) {
} }
void crawl2(jmp_buf jb, const char *path) { void crawl2(jmp_buf jb, const char *path) {
if (!strcmp(path, "/") || !strcmp(path, ".")) _gclongjmp(jb, 1); if (!strcmp(path, "/") || !strcmp(path, ".")) gclongjmp(jb, 1);
crawl2(jb, _gc(xdirname(path))); crawl2(jb, gc(xdirname(path)));
} }
void *Worker2(void *arg) { void *Worker2(void *arg) {
@ -111,7 +109,7 @@ void *Worker2(void *arg) {
return 0; return 0;
} }
TEST(_gclongjmp, torture) { TEST(gclongjmp, torture) {
int i, n = 32; int i, n = 32;
pthread_t *t = gc(malloc(sizeof(pthread_t) * n)); pthread_t *t = gc(malloc(sizeof(pthread_t) * n));
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {

View file

@ -19,7 +19,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/intrin/safemacros.internal.h" #include "libc/intrin/safemacros.internal.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/kompressor.h" #include "libc/nexgen32e/kompressor.h"
#include "libc/nexgen32e/lz4.h" #include "libc/nexgen32e/lz4.h"

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/nexgen32e.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/nexgen32e.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/hyperion.h" #include "libc/testlib/hyperion.h"

View file

@ -36,7 +36,7 @@
#include "libc/intrin/safemacros.internal.h" #include "libc/intrin/safemacros.internal.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/proc/proc.internal.h" #include "libc/proc/proc.internal.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
@ -245,7 +245,7 @@ void *Torturer(void *arg) {
TEST(posix_spawn, agony) { TEST(posix_spawn, agony) {
int i, n = 4; int i, n = 4;
pthread_t *t = _gc(malloc(sizeof(pthread_t) * n)); pthread_t *t = gc(malloc(sizeof(pthread_t) * n));
testlib_extract("/zip/echo.com", "echo.com", 0755); testlib_extract("/zip/echo.com", "echo.com", 0755);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
ASSERT_EQ(0, pthread_create(t + i, 0, Torturer, 0)); ASSERT_EQ(0, pthread_create(t + i, 0, Torturer, 0));

View file

@ -21,7 +21,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/paths.h" #include "libc/paths.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
@ -73,7 +73,7 @@ TEST(system, haveShell) {
TEST(system, echo) { TEST(system, echo) {
ASSERT_EQ(0, system("echo hello >\"hello there.txt\"")); ASSERT_EQ(0, system("echo hello >\"hello there.txt\""));
EXPECT_STREQ("hello\n", _gc(xslurp("hello there.txt", 0))); EXPECT_STREQ("hello\n", gc(xslurp("hello there.txt", 0)));
} }
TEST(system, exit) { TEST(system, exit) {
@ -83,13 +83,13 @@ TEST(system, exit) {
TEST(system, testStdoutRedirect) { TEST(system, testStdoutRedirect) {
testlib_extract("/zip/echo.com", "echo.com", 0755); testlib_extract("/zip/echo.com", "echo.com", 0755);
ASSERT_EQ(0, system("./echo.com hello >hello.txt")); ASSERT_EQ(0, system("./echo.com hello >hello.txt"));
EXPECT_STREQ("hello\n", _gc(xslurp("hello.txt", 0))); EXPECT_STREQ("hello\n", gc(xslurp("hello.txt", 0)));
} }
TEST(system, testStdoutRedirect_withSpacesInFilename) { TEST(system, testStdoutRedirect_withSpacesInFilename) {
testlib_extract("/zip/echo.com", "echo.com", 0755); testlib_extract("/zip/echo.com", "echo.com", 0755);
ASSERT_EQ(0, system("./echo.com hello >\"hello there.txt\"")); ASSERT_EQ(0, system("./echo.com hello >\"hello there.txt\""));
EXPECT_STREQ("hello\n", _gc(xslurp("hello there.txt", 0))); EXPECT_STREQ("hello\n", gc(xslurp("hello there.txt", 0)));
} }
TEST(system, testStderrRedirect_toStdout) { TEST(system, testStderrRedirect_toStdout) {

View file

@ -33,8 +33,10 @@ o/$(MODE)/test/libc/release/smoke.o: \
-o $@ \ -o $@ \
-c \ -c \
-Os \ -Os \
-Werror \
-fno-pie \ -fno-pie \
-nostdinc \ -nostdinc \
-D_COSMO_SOURCE \
-Wl,--gc-sections \ -Wl,--gc-sections \
-fno-omit-frame-pointer \ -fno-omit-frame-pointer \
-include o/cosmopolitan.h \ -include o/cosmopolitan.h \
@ -114,10 +116,12 @@ o/$(MODE)/test/libc/release/smoke-chibicc.o: \
-c \ -c \
-Os \ -Os \
-static \ -static \
-Werror \
-fno-pie \ -fno-pie \
-nostdlib \ -nostdlib \
-nostdinc \ -nostdinc \
-mno-red-zone \ -mno-red-zone \
-D_COSMO_SOURCE \
-fno-omit-frame-pointer \ -fno-omit-frame-pointer \
-include o/cosmopolitan.h \ -include o/cosmopolitan.h \
$< $<
@ -188,9 +192,11 @@ o/$(MODE)/test/libc/release/smokeansi.o: \
-c \ -c \
-Os \ -Os \
-ansi \ -ansi \
-Werror \
-static \ -static \
-fno-pie \ -fno-pie \
-nostdinc \ -nostdinc \
-D_COSMO_SOURCE \
-Wl,--gc-sections \ -Wl,--gc-sections \
-fno-omit-frame-pointer \ -fno-omit-frame-pointer \
-include o/cosmopolitan.h \ -include o/cosmopolitan.h \

View file

@ -6,8 +6,8 @@ int main(int argc, char *argv[]) {
s = strdup(argv[0]); s = strdup(argv[0]);
s[0] = 'Z'; s[0] = 'Z';
f = fopen("/dev/null", "w"); f = fopen("/dev/null", "w");
fputs(_gc(xiso8601ts(NULL)), f); /* fputs(gc(xiso8601ts(NULL)), f); */
fputs(_gc(xasprintf("hello world %d %s\n", argc, s)), f); fputs(gc(xasprintf("hello world %d %s\n", argc, s)), f);
fclose(f); fclose(f);
free(s); free(s);
return 0; return 0;

View file

@ -1,6 +1,4 @@
int main() { int main() {
int rc;
FILE *f;
int *x = new int[32]; int *x = new int[32];
x[0] = 2; x[0] = 2;
x[1] = 2; x[1] = 2;

View file

@ -35,7 +35,7 @@ TEST(ftrace, test) {
} }
const char *ftraceasm; const char *ftraceasm;
testlib_extract("/zip/ftraceasm.txt", "ftraceasm.txt", 0755); testlib_extract("/zip/ftraceasm.txt", "ftraceasm.txt", 0755);
ftraceasm = _gc(xslurp("ftraceasm.txt", 0)); ftraceasm = gc(xslurp("ftraceasm.txt", 0));
#ifdef __x86_64__ #ifdef __x86_64__
if (strstr(ftraceasm, "%xmm") || // if (strstr(ftraceasm, "%xmm") || //
strstr(ftraceasm, "%ymm") || // strstr(ftraceasm, "%ymm") || //

View file

@ -236,15 +236,15 @@ TEST(isheap, nullPtr) {
} }
TEST(isheap, malloc) { TEST(isheap, malloc) {
ASSERT_TRUE(_isheap(_gc(malloc(1)))); ASSERT_TRUE(_isheap(gc(malloc(1))));
} }
/* TEST(isheap, emptyMalloc) { */ /* TEST(isheap, emptyMalloc) { */
/* ASSERT_TRUE(_isheap(_gc(malloc(0)))); */ /* ASSERT_TRUE(_isheap(gc(malloc(0)))); */
/* } */ /* } */
/* TEST(isheap, mallocOffset) { */ /* TEST(isheap, mallocOffset) { */
/* char *p = _gc(malloc(131072)); */ /* char *p = gc(malloc(131072)); */
/* ASSERT_TRUE(_isheap(p + 100000)); */ /* ASSERT_TRUE(_isheap(p + 100000)); */
/* } */ /* } */

View file

@ -23,7 +23,7 @@
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -21,7 +21,7 @@
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/zipos.internal.h" #include "libc/runtime/zipos.internal.h"

View file

@ -22,7 +22,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"

View file

@ -18,7 +18,7 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
#include "libc/sock/struct/msghdr.h" #include "libc/sock/struct/msghdr.h"

View file

@ -19,7 +19,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"

View file

@ -27,7 +27,7 @@
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/critbit0.h" #include "libc/mem/critbit0.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/append.h" #include "libc/stdio/append.h"

View file

@ -21,7 +21,7 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/math.h" #include "libc/math.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/vendor.internal.h" #include "libc/nexgen32e/vendor.internal.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"

View file

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.h"
#include "libc/stdio/hex.internal.h" #include "libc/stdio/hex.internal.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/hyperion.h" #include "libc/testlib/hyperion.h"

View file

@ -25,7 +25,7 @@
TEST(fcvt, test) { TEST(fcvt, test) {
int decpt, sign; int decpt, sign;
ASSERT_STREQ("3.14159265358979", ASSERT_STREQ("3.14159265358979",
_gc(xasprintf("%.14f", 3.14159265358979323846))); gc(xasprintf("%.14f", 3.14159265358979323846)));
ASSERT_STREQ("3141592653589793", ASSERT_STREQ("3141592653589793",
fcvt(3.14159265358979323846, 15, &decpt, &sign)); fcvt(3.14159265358979323846, 15, &decpt, &sign));
ASSERT_EQ(1, decpt); ASSERT_EQ(1, decpt);

Some files were not shown because too many files have changed in this diff Show more