mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Make more fixups and quality assurance
This commit is contained in:
parent
85c58be942
commit
dcf9596620
17 changed files with 80 additions and 78 deletions
|
@ -21,7 +21,6 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/describeflags.h"
|
#include "libc/intrin/describeflags.h"
|
||||||
#include "libc/intrin/strace.h"
|
#include "libc/intrin/strace.h"
|
||||||
#include "libc/stdckdint.h"
|
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,7 +56,6 @@ static textwindows int sys_pipe_nt_impl(int pipefd[2], unsigned flags) {
|
||||||
__fds_unlock();
|
__fds_unlock();
|
||||||
hin = CreateNamedPipe(pipename, kNtPipeAccessInbound | kNtFileFlagOverlapped,
|
hin = CreateNamedPipe(pipename, kNtPipeAccessInbound | kNtFileFlagOverlapped,
|
||||||
mode, 1, PIPE_BUF, PIPE_BUF, 0, &kNtIsInheritable);
|
mode, 1, PIPE_BUF, PIPE_BUF, 0, &kNtIsInheritable);
|
||||||
__fds_lock();
|
|
||||||
if (hin != -1) {
|
if (hin != -1) {
|
||||||
if ((hout = CreateFile(
|
if ((hout = CreateFile(
|
||||||
pipename, kNtGenericWrite,
|
pipename, kNtGenericWrite,
|
||||||
|
@ -73,7 +72,6 @@ static textwindows int sys_pipe_nt_impl(int pipefd[2], unsigned flags) {
|
||||||
g_fds.p[writer].handle = hout;
|
g_fds.p[writer].handle = hout;
|
||||||
pipefd[0] = reader;
|
pipefd[0] = reader;
|
||||||
pipefd[1] = writer;
|
pipefd[1] = writer;
|
||||||
__fds_unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
CloseHandle(hin);
|
CloseHandle(hin);
|
||||||
|
@ -81,7 +79,6 @@ static textwindows int sys_pipe_nt_impl(int pipefd[2], unsigned flags) {
|
||||||
}
|
}
|
||||||
__releasefd(writer);
|
__releasefd(writer);
|
||||||
__releasefd(reader);
|
__releasefd(reader);
|
||||||
__fds_unlock();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,13 +351,14 @@ textwindows static int sys_poll_nt_impl(struct pollfd *fds, uint64_t nfds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint32_t *ms,
|
textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds,
|
||||||
|
const struct timespec *relative,
|
||||||
const sigset_t *sigmask) {
|
const sigset_t *sigmask) {
|
||||||
int rc;
|
int rc;
|
||||||
struct timespec now, timeout, deadline;
|
struct timespec now, timeout, deadline;
|
||||||
BLOCK_SIGNALS;
|
BLOCK_SIGNALS;
|
||||||
now = ms ? sys_clock_gettime_monotonic_nt() : timespec_zero;
|
now = relative ? sys_clock_gettime_monotonic_nt() : timespec_zero;
|
||||||
timeout = ms ? timespec_frommillis(*ms) : timespec_max;
|
timeout = relative ? *relative : timespec_max;
|
||||||
deadline = timespec_add(now, timeout);
|
deadline = timespec_add(now, timeout);
|
||||||
rc = sys_poll_nt_impl(fds, nfds, deadline, sigmask ? *sigmask : _SigMask);
|
rc = sys_poll_nt_impl(fds, nfds, deadline, sigmask ? *sigmask : _SigMask);
|
||||||
ALLOW_SIGNALS;
|
ALLOW_SIGNALS;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/strace.h"
|
#include "libc/intrin/strace.h"
|
||||||
|
#include "libc/limits.h"
|
||||||
#include "libc/runtime/stack.h"
|
#include "libc/runtime/stack.h"
|
||||||
#include "libc/sock/struct/pollfd.h"
|
#include "libc/sock/struct/pollfd.h"
|
||||||
#include "libc/sock/struct/pollfd.internal.h"
|
#include "libc/sock/struct/pollfd.internal.h"
|
||||||
|
@ -76,10 +77,13 @@ static int ppoll_impl(struct pollfd *fds, size_t nfds,
|
||||||
}
|
}
|
||||||
fdcount = sys_ppoll(fds, nfds, tsp, sigmask, 8);
|
fdcount = sys_ppoll(fds, nfds, tsp, sigmask, 8);
|
||||||
if (fdcount == -1 && errno == ENOSYS) {
|
if (fdcount == -1 && errno == ENOSYS) {
|
||||||
int ms;
|
int64_t ms;
|
||||||
errno = e;
|
errno = e;
|
||||||
if (!timeout || ckd_add(&ms, timeout->tv_sec,
|
if (timeout) {
|
||||||
(timeout->tv_nsec + 999999) / 1000000)) {
|
ms = timespec_tomillis(*timeout);
|
||||||
|
if (ms > INT_MAX)
|
||||||
|
ms = -1;
|
||||||
|
} else {
|
||||||
ms = -1;
|
ms = -1;
|
||||||
}
|
}
|
||||||
if (sigmask)
|
if (sigmask)
|
||||||
|
@ -89,15 +93,7 @@ static int ppoll_impl(struct pollfd *fds, size_t nfds,
|
||||||
sys_sigprocmask(SIG_SETMASK, &oldmask, 0);
|
sys_sigprocmask(SIG_SETMASK, &oldmask, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t ms;
|
fdcount = sys_poll_nt(fds, nfds, timeout, sigmask);
|
||||||
uint32_t *msp;
|
|
||||||
if (timeout &&
|
|
||||||
!ckd_add(&ms, timeout->tv_sec, (timeout->tv_nsec + 999999) / 1000000)) {
|
|
||||||
msp = &ms;
|
|
||||||
} else {
|
|
||||||
msp = 0;
|
|
||||||
}
|
|
||||||
fdcount = sys_poll_nt(fds, nfds, msp, sigmask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsOpenbsd() && fdcount != -1) {
|
if (IsOpenbsd() && fdcount != -1) {
|
||||||
|
|
|
@ -67,7 +67,6 @@
|
||||||
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
const struct timespec *timeout, const sigset_t *sigmask) {
|
const struct timespec *timeout, const sigset_t *sigmask) {
|
||||||
int rc;
|
int rc;
|
||||||
struct timeval tv, *tvp;
|
|
||||||
struct timespec ts, *tsp;
|
struct timespec ts, *tsp;
|
||||||
struct {
|
struct {
|
||||||
const sigset_t *s;
|
const sigset_t *s;
|
||||||
|
@ -111,14 +110,7 @@ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
rc = sys_pselect(nfds, readfds, writefds, exceptfds,
|
rc = sys_pselect(nfds, readfds, writefds, exceptfds,
|
||||||
(struct timespec *)timeout, sigmask);
|
(struct timespec *)timeout, sigmask);
|
||||||
} else {
|
} else {
|
||||||
if (timeout) {
|
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout, sigmask);
|
||||||
tv.tv_sec = timeout->tv_sec;
|
|
||||||
tv.tv_usec = timeout->tv_nsec / 1000;
|
|
||||||
tvp = &tv;
|
|
||||||
} else {
|
|
||||||
tvp = 0;
|
|
||||||
}
|
|
||||||
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, tvp, sigmask);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
END_CANCELATION_POINT;
|
END_CANCELATION_POINT;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#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/pollfd.internal.h"
|
#include "libc/sock/struct/pollfd.internal.h"
|
||||||
#include "libc/stdckdint.h"
|
|
||||||
#include "libc/sysv/consts/poll.h"
|
#include "libc/sysv/consts/poll.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
@ -44,7 +43,7 @@
|
||||||
// </sync libc/sysv/consts.sh>
|
// </sync libc/sysv/consts.sh>
|
||||||
|
|
||||||
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
fd_set *exceptfds, struct timeval *timeout,
|
fd_set *exceptfds, const struct timespec *timeout,
|
||||||
const sigset_t *sigmask) {
|
const sigset_t *sigmask) {
|
||||||
int pfds = 0;
|
int pfds = 0;
|
||||||
|
|
||||||
|
@ -68,21 +67,8 @@ int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the wait time to a word
|
|
||||||
uint32_t millis;
|
|
||||||
if (!timeout) {
|
|
||||||
millis = -1u;
|
|
||||||
} else {
|
|
||||||
int64_t ms = timeval_tomillis(*timeout);
|
|
||||||
if (ms < 0 || ms > UINT32_MAX) {
|
|
||||||
millis = -1u;
|
|
||||||
} else {
|
|
||||||
millis = ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// call our nt poll implementation
|
// call our nt poll implementation
|
||||||
int fdcount = sys_poll_nt(fds, pfds, &millis, sigmask);
|
int fdcount = sys_poll_nt(fds, pfds, timeout, sigmask);
|
||||||
if (fdcount == -1)
|
if (fdcount == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -115,10 +101,6 @@ int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store remaining time back in caller's timeval
|
|
||||||
if (timeout)
|
|
||||||
*timeout = timeval_frommillis(millis);
|
|
||||||
|
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,7 @@
|
||||||
* such as out-of-band data on a socket; it is equivalent to POLLPRI
|
* such as out-of-band data on a socket; it is equivalent to POLLPRI
|
||||||
* in the revents of poll()
|
* in the revents of poll()
|
||||||
* @param timeout may be null which means to block indefinitely; cosmo's
|
* @param timeout may be null which means to block indefinitely; cosmo's
|
||||||
* implementation of select() never modifies this parameter which is
|
* implementation of select() never modifies this parameter
|
||||||
* how most platforms except Linux work which modifies it to reflect
|
|
||||||
* elapsed time, noting that POSIX permits either behavior therefore
|
|
||||||
* portable code should assume that timeout memory becomes undefined
|
|
||||||
* @raise E2BIG if we exceeded the 64 socket limit on Windows
|
* @raise E2BIG if we exceeded the 64 socket limit on Windows
|
||||||
* @raise ECANCELED if thread was cancelled in masked mode
|
* @raise ECANCELED if thread was cancelled in masked mode
|
||||||
* @raise EINTR if signal was delivered
|
* @raise EINTR if signal was delivered
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/describeflags.h"
|
#include "libc/intrin/describeflags.h"
|
||||||
#include "libc/intrin/strace.h"
|
#include "libc/intrin/strace.h"
|
||||||
#include "libc/stdckdint.h"
|
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
#define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/nt/struct/overlapped.h"
|
#include "libc/nt/struct/overlapped.h"
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
|
@ -60,7 +61,7 @@ int sys_socketpair_nt_stream(int, int, int, int[2]) ;
|
||||||
int sys_socketpair_nt_dgram(int, int, int, int[2]) ;
|
int sys_socketpair_nt_dgram(int, int, int, int[2]) ;
|
||||||
*/
|
*/
|
||||||
int sys_socketpair_nt(int, int, int, int[2]);
|
int sys_socketpair_nt(int, int, int, int[2]);
|
||||||
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *,
|
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, const struct timespec *,
|
||||||
const sigset_t *);
|
const sigset_t *);
|
||||||
|
|
||||||
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *, size_t);
|
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *, size_t);
|
||||||
|
|
|
@ -66,8 +66,9 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
|
||||||
|
|
||||||
__sig_unblock(waitmask);
|
__sig_unblock(waitmask);
|
||||||
|
|
||||||
if (rc == -1 && errno == WSAESHUTDOWN) { // ESHUTDOWN
|
if (rc == -1 && (errno == WSAESHUTDOWN || // ESHUTDOWN
|
||||||
errno = kNtErrorBrokenPipe; // EPIPE
|
errno == WSAECONNABORTED)) { // ECONNABORTED
|
||||||
|
errno = kNtErrorBrokenPipe; // EPIPE
|
||||||
if (!(flags & _MSG_NOSIGNAL))
|
if (!(flags & _MSG_NOSIGNAL))
|
||||||
__sig_raise(SIGPIPE, SI_KERNEL);
|
__sig_raise(SIGPIPE, SI_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
||||||
|
|
||||||
__sig_unblock(waitmask);
|
__sig_unblock(waitmask);
|
||||||
|
|
||||||
if (rc == -1 && errno == WSAESHUTDOWN) { // ESHUTDOWN
|
if (rc == -1 && (errno == WSAESHUTDOWN || // ESHUTDOWN
|
||||||
errno = kNtErrorBrokenPipe; // EPIPE
|
errno == WSAECONNABORTED)) { // ECONNABORTED
|
||||||
|
errno = kNtErrorBrokenPipe; // EPIPE
|
||||||
if (!(flags & _MSG_NOSIGNAL))
|
if (!(flags & _MSG_NOSIGNAL))
|
||||||
__sig_raise(SIGPIPE, SI_KERNEL);
|
__sig_raise(SIGPIPE, SI_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ int32_t __sys_poll(struct pollfd *, uint64_t, signed);
|
||||||
int sys_ppoll(struct pollfd *, size_t, const struct timespec *,
|
int sys_ppoll(struct pollfd *, size_t, const struct timespec *,
|
||||||
const sigset_t *, size_t);
|
const sigset_t *, size_t);
|
||||||
int sys_poll_metal(struct pollfd *, size_t, unsigned);
|
int sys_poll_metal(struct pollfd *, size_t, unsigned);
|
||||||
int sys_poll_nt(struct pollfd *, uint64_t, uint32_t *, const sigset_t *);
|
int sys_poll_nt(struct pollfd *, uint64_t, const struct timespec *,
|
||||||
|
const sigset_t *);
|
||||||
|
|
||||||
const char *_DescribePollFds(char[300], ssize_t, struct pollfd *, size_t);
|
const char *_DescribePollFds(char[300], ssize_t, struct pollfd *, size_t);
|
||||||
#define DescribePollFds(x, y, z) _DescribePollFds(alloca(300), x, y, z)
|
#define DescribePollFds(x, y, z) _DescribePollFds(alloca(300), x, y, z)
|
||||||
|
|
|
@ -74,9 +74,8 @@ size_t fwrite_unlocked(const void *data, size_t stride, size_t count, FILE *f) {
|
||||||
size_t n, m;
|
size_t n, m;
|
||||||
const char *p;
|
const char *p;
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
if (!stride || !count) {
|
if (!stride || !count)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if ((f->iomode & O_ACCMODE) == O_RDONLY) {
|
if ((f->iomode & O_ACCMODE) == O_RDONLY) {
|
||||||
f->state = errno = EBADF;
|
f->state = errno = EBADF;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/fmt/internal.h"
|
#include "libc/fmt/internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/stdckdint.h"
|
#include "libc/stdckdint.h"
|
||||||
#include "libc/stdio/internal.h"
|
#include "libc/stdio/internal.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
@ -46,9 +47,8 @@ static int __vfprintf_flbuf(const char *s, struct state *t, size_t n) {
|
||||||
} else {
|
} else {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
if (ckd_add(&t->n, t->n, n)) {
|
if (ckd_add(&t->n, t->n, n))
|
||||||
rc = eoverflow();
|
rc = eoverflow();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
@ -60,9 +60,8 @@ static int __vfprintf_nbuf(const char *s, struct state *t, size_t n) {
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
t->b.p[t->b.n++] = s[i];
|
t->b.p[t->b.n++] = s[i];
|
||||||
if (t->b.n == sizeof(t->b.p)) {
|
if (t->b.n == sizeof(t->b.p)) {
|
||||||
if (!fwrite_unlocked(t->b.p, 1, t->b.n, t->f)) {
|
if (!fwrite_unlocked(t->b.p, 1, t->b.n, t->f))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
t->b.n = 0;
|
t->b.n = 0;
|
||||||
} else if (ckd_add(&t->n, t->n, 1)) {
|
} else if (ckd_add(&t->n, t->n, 1)) {
|
||||||
return eoverflow();
|
return eoverflow();
|
||||||
|
@ -91,9 +90,7 @@ int vfprintf_unlocked(FILE *f, const char *fmt, va_list va) {
|
||||||
if (!st.b.n) {
|
if (!st.b.n) {
|
||||||
rc = st.n;
|
rc = st.n;
|
||||||
} else if (fwrite_unlocked(st.b.p, 1, st.b.n, st.f)) {
|
} else if (fwrite_unlocked(st.b.p, 1, st.b.n, st.f)) {
|
||||||
if (ckd_add(&rc, st.n, st.b.n)) {
|
rc = st.n;
|
||||||
rc = eoverflow();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
|
43
test/posix/printf_return_test.c
Normal file
43
test/posix/printf_return_test.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright 2024 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 <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
if (close(1))
|
||||||
|
return 1;
|
||||||
|
if (open("/dev/null", O_WRONLY) != 1)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if (printf("a") != 1)
|
||||||
|
return 4;
|
||||||
|
if (printf("%s", "") != 0)
|
||||||
|
return 5;
|
||||||
|
if (printf("%s", "a") != 1)
|
||||||
|
return 6;
|
||||||
|
if (printf("%10s", "a") != 10)
|
||||||
|
return 6;
|
||||||
|
if (printf("%-10s", "a") != 10)
|
||||||
|
return 6;
|
||||||
|
if (printf("%-10s%-40s %9s %8s %8s %8s\n", "Benchmark", "prog", "ops",
|
||||||
|
"time", "ops/sec", "time/op") != 89)
|
||||||
|
return 7;
|
||||||
|
if (fprintf(stdout, "%-10s%-40s %9s %8s %8s %8s\n", "Benchmark", "prog",
|
||||||
|
"ops", "time", "ops/sec", "time/op") != 89)
|
||||||
|
return 8;
|
||||||
|
}
|
4
third_party/nsync/README.cosmo
vendored
4
third_party/nsync/README.cosmo
vendored
|
@ -33,10 +33,6 @@ LOCAL CHANGES
|
||||||
lets us use weak cas when appropriate. It also avoids a superfluous
|
lets us use weak cas when appropriate. It also avoids a superfluous
|
||||||
relaxed load on failure. This mostly impacts aarch64, not x86_64.
|
relaxed load on failure. This mostly impacts aarch64, not x86_64.
|
||||||
|
|
||||||
- Modified *NSYNC to allocate waiter objects on the stack. We need it
|
|
||||||
because we use *NSYNC mutexes to implement POSIX mutexes, which are
|
|
||||||
too low-level to safely depend on malloc, or even mmap in our case.
|
|
||||||
|
|
||||||
- Rewrote most of the semaphore and futex system call support code so
|
- Rewrote most of the semaphore and futex system call support code so
|
||||||
it works well with Cosmopolitan's fat runtime portability. *NSYNC's
|
it works well with Cosmopolitan's fat runtime portability. *NSYNC's
|
||||||
unit test suite passes on all supported platforms. However the BSDs
|
unit test suite passes on all supported platforms. However the BSDs
|
||||||
|
|
12
third_party/nsync/mu.c
vendored
12
third_party/nsync/mu.c
vendored
|
@ -477,9 +477,9 @@ void nsync_mu_unlock (nsync_mu *mu) {
|
||||||
and deallocate the mutex before the current thread touched the mutex
|
and deallocate the mutex before the current thread touched the mutex
|
||||||
word again. */
|
word again. */
|
||||||
uint32_t old_word = MU_WLOCK;
|
uint32_t old_word = MU_WLOCK;
|
||||||
if (!atomic_compare_exchange_weak_explicit (&mu->word, &old_word, 0,
|
if (!atomic_compare_exchange_strong_explicit (&mu->word, &old_word, 0,
|
||||||
memory_order_release,
|
memory_order_release,
|
||||||
memory_order_relaxed)) {
|
memory_order_relaxed)) {
|
||||||
/* Clear MU_ALL_FALSE because the critical section we're just
|
/* Clear MU_ALL_FALSE because the critical section we're just
|
||||||
leaving may have made some conditions true. */
|
leaving may have made some conditions true. */
|
||||||
uint32_t new_word = (old_word - MU_WLOCK) & ~MU_ALL_FALSE;
|
uint32_t new_word = (old_word - MU_WLOCK) & ~MU_ALL_FALSE;
|
||||||
|
@ -508,9 +508,9 @@ void nsync_mu_runlock (nsync_mu *mu) {
|
||||||
IGNORE_RACES_START ();
|
IGNORE_RACES_START ();
|
||||||
/* See comment in nsync_mu_unlock(). */
|
/* See comment in nsync_mu_unlock(). */
|
||||||
uint32_t old_word = MU_RLOCK;
|
uint32_t old_word = MU_RLOCK;
|
||||||
if (!atomic_compare_exchange_weak_explicit (&mu->word, &old_word, 0,
|
if (!atomic_compare_exchange_strong_explicit (&mu->word, &old_word, 0,
|
||||||
memory_order_release,
|
memory_order_release,
|
||||||
memory_order_relaxed)) {
|
memory_order_relaxed)) {
|
||||||
/* Sanity check: mutex must not be held in write mode and
|
/* Sanity check: mutex must not be held in write mode and
|
||||||
reader count must not be 0. */
|
reader count must not be 0. */
|
||||||
if (((old_word ^ MU_WLOCK) & (MU_WLOCK | MU_RLOCK_FIELD)) == 0) {
|
if (((old_word ^ MU_WLOCK) & (MU_WLOCK | MU_RLOCK_FIELD)) == 0) {
|
||||||
|
|
Loading…
Reference in a new issue