mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 03:08:31 +00:00
Improve system call wrappers
This change improves copy_file_range(), sendfile(), splice(), openpty(), closefrom(), close_range(), fadvise() and posix_fadvise() in addition to writing tests that confirm things like errno and seeking behavior across platforms. We now less aggressively polyfill behavior with some of these functions when the platform support isn't available. Please see: https://justine.lol/cosmopolitan/functions.html
This commit is contained in:
parent
224c12f54d
commit
c7a8cd21e9
89 changed files with 1151 additions and 414 deletions
|
@ -24,7 +24,8 @@
|
|||
* @param guardsize will be set to guard size in bytes
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) {
|
||||
errno_t pthread_attr_getguardsize(const pthread_attr_t *attr,
|
||||
size_t *guardsize) {
|
||||
*guardsize = attr->guardsize;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
/**
|
||||
* Returns configuration for thread stack.
|
||||
|
@ -30,8 +30,8 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @see pthread_attr_setstacksize()
|
||||
*/
|
||||
int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr,
|
||||
size_t *stacksize) {
|
||||
errno_t pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr,
|
||||
size_t *stacksize) {
|
||||
*stackaddr = attr->stackaddr;
|
||||
*stacksize = attr->stacksize;
|
||||
return 0;
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
/**
|
||||
* Returns size of thread stack.
|
||||
|
@ -28,7 +28,7 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @see pthread_attr_setstacksize()
|
||||
*/
|
||||
int pthread_attr_getstacksize(const pthread_attr_t *a, size_t *x) {
|
||||
errno_t pthread_attr_getstacksize(const pthread_attr_t *a, size_t *x) {
|
||||
if (a->stacksize) {
|
||||
*x = a->stacksize;
|
||||
} else {
|
||||
|
|
|
@ -16,15 +16,15 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
/**
|
||||
* Initializes pthread attributes.
|
||||
*
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int pthread_attr_init(pthread_attr_t *attr) {
|
||||
errno_t pthread_attr_init(pthread_attr_t *attr) {
|
||||
*attr = (pthread_attr_t){
|
||||
.stacksize = GetStackSize(),
|
||||
.guardsize = PAGESIZE,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param guardsize contains guard size in bytes
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) {
|
||||
errno_t pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) {
|
||||
attr->guardsize = guardsize;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise EINVAL on bad value
|
||||
*/
|
||||
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) {
|
||||
errno_t pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) {
|
||||
switch (inheritsched) {
|
||||
case PTHREAD_INHERIT_SCHED:
|
||||
case PTHREAD_EXPLICIT_SCHED:
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
* @raise EINVAL if parameters were unacceptable
|
||||
* @see pthread_attr_setstacksize()
|
||||
*/
|
||||
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
|
||||
size_t stacksize) {
|
||||
errno_t pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
|
||||
size_t stacksize) {
|
||||
if (!stackaddr) {
|
||||
attr->stackaddr = 0;
|
||||
attr->stacksize = 0;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise EINVAL if `stacksize` is less than `PTHREAD_STACK_MIN`
|
||||
*/
|
||||
int pthread_attr_setstacksize(pthread_attr_t *a, size_t stacksize) {
|
||||
errno_t pthread_attr_setstacksize(pthread_attr_t *a, size_t stacksize) {
|
||||
if (stacksize < PTHREAD_STACK_MIN) return EINVAL;
|
||||
a->stacksize = stacksize;
|
||||
return 0;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
* @return 0 on success, `PTHREAD_BARRIER_SERIAL_THREAD` to one lucky
|
||||
* thread which was the last arrival, or an errno on error
|
||||
*/
|
||||
int pthread_barrier_wait(pthread_barrier_t *barrier) {
|
||||
errno_t pthread_barrier_wait(pthread_barrier_t *barrier) {
|
||||
if (nsync_counter_add(barrier->_nsync, -1)) {
|
||||
nsync_counter_wait(barrier->_nsync, nsync_time_no_deadline);
|
||||
return 0;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* @see pthread_cond_signal
|
||||
* @see pthread_cond_wait
|
||||
*/
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond) {
|
||||
errno_t pthread_cond_broadcast(pthread_cond_t *cond) {
|
||||
nsync_cv_broadcast((nsync_cv *)cond);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* @see pthread_cond_broadcast
|
||||
* @see pthread_cond_wait
|
||||
*/
|
||||
int pthread_cond_signal(pthread_cond_t *cond) {
|
||||
errno_t pthread_cond_signal(pthread_cond_t *cond) {
|
||||
nsync_cv_signal((nsync_cv *)cond);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
* @see pthread_cond_broadcast
|
||||
* @see pthread_cond_signal
|
||||
*/
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime) {
|
||||
errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime) {
|
||||
if (abstime && !(0 <= abstime->tv_nsec && abstime->tv_nsec < 1000000000)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
* @see pthread_cond_broadcast
|
||||
* @see pthread_cond_signal
|
||||
*/
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
|
||||
errno_t pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
|
||||
return pthread_cond_timedwait(cond, mutex, 0);
|
||||
}
|
||||
|
|
|
@ -184,8 +184,8 @@ static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) {
|
|||
* isn't authorized to use it
|
||||
* @threadsafe
|
||||
*/
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg) {
|
||||
errno_t pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg) {
|
||||
int rc, e = errno;
|
||||
struct PosixThread *pt;
|
||||
__require_tls();
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise ENOSYS if not Linux or Windows
|
||||
*/
|
||||
int pthread_getaffinity_np(pthread_t thread, size_t bitsetsize,
|
||||
cpu_set_t *bitset) {
|
||||
errno_t pthread_getaffinity_np(pthread_t thread, size_t bitsetsize,
|
||||
cpu_set_t *bitset) {
|
||||
int rc, e = errno;
|
||||
struct PosixThread *pt = (struct PosixThread *)thread;
|
||||
if (!sched_getaffinity(pt->tid, bitsetsize, bitset)) {
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
* result will still be returned truncated if possible
|
||||
* @raise ENOSYS on MacOS, Windows, FreeBSD, and OpenBSD
|
||||
*/
|
||||
int pthread_getname_np(pthread_t thread, char *name, size_t size) {
|
||||
errno_t pthread_getname_np(pthread_t thread, char *name, size_t size) {
|
||||
int e, fd, rc, tid, len;
|
||||
|
||||
if (!size) return 0;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
|
||||
errno_t pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
|
||||
nsync_mu_rlock((nsync_mu *)rwlock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise EINVAL if lock is in a bad state
|
||||
*/
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
|
||||
errno_t pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
|
||||
if (rwlock->_iswrite) {
|
||||
rwlock->_iswrite = 0;
|
||||
nsync_mu_unlock((nsync_mu *)rwlock);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
|
||||
errno_t pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
|
||||
nsync_mu_lock((nsync_mu *)rwlock);
|
||||
rwlock->_iswrite = 1;
|
||||
return 0;
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise ENOSYS if not Linux or Windows
|
||||
*/
|
||||
int pthread_setaffinity_np(pthread_t thread, size_t bitsetsize,
|
||||
const cpu_set_t *bitset) {
|
||||
errno_t pthread_setaffinity_np(pthread_t thread, size_t bitsetsize,
|
||||
const cpu_set_t *bitset) {
|
||||
int rc, e = errno;
|
||||
struct PosixThread *pt = (struct PosixThread *)thread;
|
||||
if (!sched_setaffinity(pt->tid, bitsetsize, bitset)) {
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
* @raise ENOSYS on MacOS, Windows, and OpenBSD
|
||||
* @see pthread_getname_np()
|
||||
*/
|
||||
int pthread_setname_np(pthread_t thread, const char *name) {
|
||||
errno_t pthread_setname_np(pthread_t thread, const char *name) {
|
||||
char path[128], *p;
|
||||
int e, fd, rc, tid, len;
|
||||
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
*
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
int(pthread_spin_destroy)(pthread_spinlock_t *spin) {
|
||||
errno_t(pthread_spin_destroy)(pthread_spinlock_t *spin) {
|
||||
return pthread_spin_destroy(spin);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,6 @@
|
|||
* @see pthread_spin_destroy
|
||||
* @see pthread_spin_lock
|
||||
*/
|
||||
int(pthread_spin_init)(pthread_spinlock_t *spin, int pshared) {
|
||||
errno_t(pthread_spin_init)(pthread_spinlock_t *spin, int pshared) {
|
||||
return pthread_spin_init(spin, pshared);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,6 @@
|
|||
* @see pthread_spin_unlock
|
||||
* @see pthread_spin_init
|
||||
*/
|
||||
int(pthread_spin_lock)(pthread_spinlock_t *spin) {
|
||||
errno_t(pthread_spin_lock)(pthread_spinlock_t *spin) {
|
||||
return pthread_spin_lock(spin);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,6 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @raise EBUSY if lock is already held
|
||||
*/
|
||||
int(pthread_spin_trylock)(pthread_spinlock_t *spin) {
|
||||
errno_t(pthread_spin_trylock)(pthread_spinlock_t *spin) {
|
||||
return pthread_spin_trylock(spin);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
* @return 0 on success, or errno on error
|
||||
* @see pthread_spin_lock
|
||||
*/
|
||||
int(pthread_spin_unlock)(pthread_spinlock_t *spin) {
|
||||
errno_t(pthread_spin_unlock)(pthread_spinlock_t *spin) {
|
||||
return pthread_spin_unlock(spin);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue