Improve cosmo's conformance to libc-test

This change addresses various open source compatibility issues, so that
we pass 313/411 of the tests in https://github.com/jart/libc-test where
earlier today we were passing about 30/411 of them, due to header toil.
Please note that Glibc only passes 341/411 so 313 today is pretty good!

- Make the conformance of libc/isystem/ headers nearly perfect
- Import more of the remaining math library routines from Musl
- Fix inconsistencies with type signatures of calls like umask
- Write tests for getpriority/setpriority which work great now
- conform to `struct sockaddr *` on remaining socket functions
- Import a bunch of uninteresting stdlib functions e.g. rand48
- Introduce readdir_r, scandir, pthread_kill, sigsetjmp, etc..

Follow the instructions in our `tool/scripts/cosmocc` toolchain to run
these tests yourself. You use `make CC=cosmocc` on the test repository
This commit is contained in:
Justine Tunney 2022-10-10 17:52:41 -07:00
parent 467a332e38
commit e557058ac8
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
189 changed files with 5091 additions and 884 deletions

View file

@ -61,14 +61,17 @@ enum PosixThreadStatus {
struct PosixThread {
_Atomic(enum PosixThreadStatus) status;
void *(*start_routine)(void *);
void *arg; // start_routine's parameter
void *rc; // start_routine's return value
int flags; // see PT_* constants
int tid; // clone parent tid
char *altstack; // thread sigaltstack
char *tls; // bottom of tls allocation
struct CosmoTib *tib; // middle of tls allocation
jmp_buf exiter; // for pthread_exit
void *arg; // start_routine's parameter
void *rc; // start_routine's return value
int tid; // clone parent tid
int flags; // see PT_* constants
_Atomic(int) cancelled; // thread has bad beliefs
char cancelasync; // PTHREAD_CANCEL_DEFERRED/ASYNCHRONOUS
char canceldisable; // PTHREAD_CANCEL_ENABLE/DISABLE
char *altstack; // thread sigaltstack
char *tls; // bottom of tls allocation
struct CosmoTib *tib; // middle of tls allocation
jmp_buf exiter; // for pthread_exit
pthread_attr_t attr;
struct _pthread_cleanup_buffer *cleanup;
};

View file

@ -34,7 +34,7 @@
* void OnUsr1(int sig) { gotusr1 = true; }
* struct sigaction sa = {.sa_handler = OnUsr1};
* sigaction(SIGUSR1, &sa, 0);
* tkill(pthread_getunique_np(thread), SIGUSR1);
* pthread_kill(thread, SIGUSR1);
*
* The above code should successfully cancel a thread's blocking io
* operations in most cases, e.g.
@ -61,7 +61,7 @@
* @see https://sourceware.org/bugzilla/show_bug.cgi?id=12683
*/
int pthread_cancel(pthread_t thread) {
kprintf("error: pthread_cancel() is unsupported, please read the "
"cosmopolitan libc documentation for further details\n");
kprintf("error: pthread_cancel() isn't supported, please see the"
" cosmopolitan libc documentation for further details\n");
_Exit(1);
}

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/thread/thread.h"
#include "libc/thread/posixthread.internal.h"
/**
* Compares thread ids;
@ -25,7 +24,5 @@
* @return nonzero if equal, otherwise zero
*/
int pthread_equal(pthread_t t1, pthread_t t2) {
struct PosixThread *a = (struct PosixThread *)t1;
struct PosixThread *b = (struct PosixThread *)t2;
return a->tid == b->tid;
return t1 == t2;
}

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/limits.h"
#include "libc/mem/gc.h"
#include "libc/runtime/runtime.h"
@ -25,8 +26,6 @@
#include "libc/thread/tls.h"
#include "third_party/nsync/futex.internal.h"
STATIC_YOINK("_pthread_main");
/**
* Terminates current POSIX thread.
*
@ -86,7 +85,7 @@ wontreturn void pthread_exit(void *rc) {
// this implementation so much simpler for example we want't to call
// set_tid_address() upon every program startup which isn't possible
// on non-linux platforms anyway.
__get_tls()->tib_tid = 0;
atomic_store_explicit(&__get_tls()->tib_tid, 0, memory_order_release);
nsync_futex_wake_((int *)&__get_tls()->tib_tid, INT_MAX, !IsWindows());
_Exit1(0);
}

View file

@ -0,0 +1,43 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
/**
* Sends signal to thread.
*
* @return 0 on success, or errno on error
* @raise ESRCH if `tid` was valid but no such thread existed
* @raise EAGAIN if `RLIMIT_SIGPENDING` was exceeded
* @raise EINVAL if `tid` or `sig` was invalid
* @raise EPERM if permission was denied
*/
int pthread_kill(pthread_t thread, int sig) {
int rc, e = errno;
struct PosixThread *pt = (struct PosixThread *)thread;
if (!tkill(pt->tid, sig)) {
rc = 0;
} else {
rc = errno;
errno = e;
}
return rc;
}

View file

@ -16,14 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
STATIC_YOINK("_pthread_main");
/**
* Returns current POSIX thread.
*/
pthread_t pthread_self(void) {
return __get_tls()->tib_pthread;
pthread_t t;
t = __get_tls()->tib_pthread;
_unassert(t);
return t;
}

View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
/**
* Sets cancelability state.
*
* @param state may be one of:
* - `PTHREAD_CANCEL_ENABLE` (default)
* - `PTHREAD_CANCEL_DISABLE`
* @param oldstate optionally receives old value
* @return 0 on success, or errno on error
* @raise EINVAL if `state` has bad value
* @see pthread_cancel() for docs
*/
int pthread_setcancelstate(int state, int *oldstate) {
struct PosixThread *pt;
switch (state) {
case PTHREAD_CANCEL_ENABLE:
case PTHREAD_CANCEL_DISABLE:
pt = (struct PosixThread *)__get_tls()->tib_pthread;
if (oldstate) *oldstate = pt->canceldisable;
pt->canceldisable = state;
return 0;
default:
return EINVAL;
}
}

View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
/**
* Sets cancellation strategy.
*
* @param type may be one of:
* - `PTHREAD_CANCEL_DEFERRED` (default)
* - `PTHREAD_CANCEL_ASYNCHRONOUS`
* @param oldtype optionally receives old value
* @return 0 on success, or errno on error
* @raise EINVAL if `type` has bad value
* @see pthread_cancel() for docs
*/
int pthread_setcanceltype(int type, int *oldtype) {
struct PosixThread *pt;
switch (type) {
case PTHREAD_CANCEL_DEFERRED:
case PTHREAD_CANCEL_ASYNCHRONOUS:
pt = (struct PosixThread *)__get_tls()->tib_pthread;
if (oldtype) *oldtype = pt->cancelasync;
pt->cancelasync = type;
return 0;
default:
return EINVAL;
}
}

View file

@ -16,16 +16,14 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
// it's only be possible for this memory to be accessed when the user
// has linked either pthread_self() or pthread_exit() which yoink it.
struct PosixThread _pthread_main;
__attribute__((__constructor__)) static void pthread_self_init(void) {
_pthread_main.tid = gettid();
_pthread_main.tib = __get_tls();
_pthread_main.flags = PT_MAINTHREAD;
__get_tls()->tib_pthread = (pthread_t)&_pthread_main;
/**
* Sets scheduler parameter on thread.
*/
int pthread_setschedprio(pthread_t thread, int prio) {
struct PosixThread *pt = (struct PosixThread *)thread;
pt->attr.__schedparam = prio;
return _pthread_reschedule(pt);
}

View file

@ -23,6 +23,14 @@
#define PTHREAD_INHERIT_SCHED 0
#define PTHREAD_EXPLICIT_SCHED 1
#define PTHREAD_CANCELED ((void *)-1)
#define PTHREAD_CANCEL_ENABLE 0
#define PTHREAD_CANCEL_DISABLE 1
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 1
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -122,7 +130,11 @@ int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
int pthread_attr_getstacksize(const pthread_attr_t *, size_t *);
int pthread_attr_setstacksize(pthread_attr_t *, size_t);
int pthread_detach(pthread_t);
int pthread_kill(pthread_t, int);
int pthread_cancel(pthread_t);
int pthread_setcanceltype(int, int *);
int pthread_setcancelstate(int, int *);
int pthread_setschedprio(pthread_t, int);
int pthread_join(pthread_t, void **);
int pthread_equal(pthread_t, pthread_t);
int pthread_once(pthread_once_t *, void (*)(void));
@ -165,7 +177,7 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t *);
int pthread_rwlock_unlock(pthread_rwlock_t *);
int pthread_key_create(pthread_key_t *, pthread_key_dtor);
int pthread_key_delete(pthread_key_t);
int pthread_setspecific(pthread_key_t, void *);
int pthread_setspecific(pthread_key_t, const void *);
void *pthread_getspecific(pthread_key_t);
int pthread_barrierattr_init(pthread_barrierattr_t *);
int pthread_barrierattr_destroy(pthread_barrierattr_t *);