mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-22 18:40:29 +00:00
Fix some issues
This commit is contained in:
parent
211d5d902e
commit
9d372f48dd
29 changed files with 373 additions and 63 deletions
|
@ -29,7 +29,7 @@
|
|||
void __assert_fail(const char *expr, const char *file, int line) {
|
||||
char ibuf[12];
|
||||
FormatInt32(ibuf, line);
|
||||
tinyprint(2, "\n", file, ":", ibuf, ": assert(", expr, ") failed (",
|
||||
tinyprint(2, file, ":", ibuf, ": assert(", expr, ") failed (",
|
||||
program_invocation_short_name, " ",
|
||||
DescribeBacktrace(__builtin_frame_address(0)), ")\n", NULL);
|
||||
abort();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
|
||||
|
@ -74,7 +76,7 @@ int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
|
|||
}
|
||||
if (res == -EINTR && //
|
||||
(_weaken(pthread_testcancel_np) && //
|
||||
_weaken(pthread_testcancel_np))) {
|
||||
_weaken(pthread_testcancel_np)())) {
|
||||
return ecanceled();
|
||||
}
|
||||
return _sysret(res);
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/runtime/clktck.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
static int sys_clock_nanosleep(int clock, int flags, //
|
||||
const struct timespec *req,
|
||||
|
@ -45,6 +48,16 @@ static int sys_clock_nanosleep(int clock, int flags, //
|
|||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
if (rc > 0) {
|
||||
errno = rc;
|
||||
rc = -1;
|
||||
}
|
||||
// system call support might not detect cancelation on bsds
|
||||
if (rc == -1 && errno == EINTR && //
|
||||
_weaken(pthread_testcancel_np) && //
|
||||
_weaken(pthread_testcancel_np)()) {
|
||||
rc = ecanceled();
|
||||
}
|
||||
END_CANCELATION_POINT;
|
||||
STRACE("sys_clock_nanosleep(%s, %s, %s, [%s]) → %d% m",
|
||||
DescribeClockName(clock), DescribeSleepFlags(flags),
|
||||
|
@ -62,11 +75,11 @@ static int cosmo_clock_nanosleep(int clock, int flags,
|
|||
if (clock == CLOCK_REALTIME || //
|
||||
clock == CLOCK_REALTIME_PRECISE) {
|
||||
time_clock = clock;
|
||||
sleep_clock = CLOCK_REALTIME_PRECISE;
|
||||
sleep_clock = CLOCK_REALTIME;
|
||||
} else if (clock == CLOCK_MONOTONIC || //
|
||||
clock == CLOCK_MONOTONIC_PRECISE) {
|
||||
time_clock = clock;
|
||||
sleep_clock = CLOCK_MONOTONIC_PRECISE;
|
||||
sleep_clock = CLOCK_MONOTONIC;
|
||||
} else if (clock == CLOCK_REALTIME_COARSE || //
|
||||
clock == CLOCK_REALTIME_FAST) {
|
||||
return sys_clock_nanosleep(CLOCK_REALTIME, flags, req, rem);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/limits.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
@ -70,6 +71,10 @@ static void sigaction_cosmo2native(union metasigaction *sa) {
|
|||
sa->linux.sa_restorer = restorer;
|
||||
sa->linux.sa_mask[0] = masklo;
|
||||
sa->linux.sa_mask[1] = maskhi;
|
||||
} else if (IsXnuSilicon()) {
|
||||
sa->silicon.sa_flags = flags;
|
||||
sa->silicon.sa_handler = handler;
|
||||
sa->silicon.sa_mask[0] = masklo;
|
||||
} else if (IsXnu()) {
|
||||
sa->xnu_in.sa_flags = flags;
|
||||
sa->xnu_in.sa_handler = handler;
|
||||
|
@ -109,6 +114,10 @@ static void sigaction_native2cosmo(union metasigaction *sa) {
|
|||
restorer = sa->linux.sa_restorer;
|
||||
masklo = sa->linux.sa_mask[0];
|
||||
maskhi = sa->linux.sa_mask[1];
|
||||
} else if (IsXnu()) {
|
||||
flags = sa->silicon.sa_flags;
|
||||
handler = sa->silicon.sa_handler;
|
||||
masklo = sa->silicon.sa_mask[0];
|
||||
} else if (IsXnu()) {
|
||||
flags = sa->xnu_out.sa_flags;
|
||||
handler = sa->xnu_out.sa_handler;
|
||||
|
@ -142,6 +151,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
(sizeof(struct sigaction) >= sizeof(struct sigaction_linux) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_in) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_out) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_silicon) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_freebsd) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_openbsd) &&
|
||||
sizeof(struct sigaction) >= sizeof(struct sigaction_netbsd)),
|
||||
|
@ -193,6 +203,9 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
// mitigate Rosetta signal handling strangeness
|
||||
// https://github.com/jart/cosmopolitan/issues/455
|
||||
ap->sa_flags |= SA_SIGINFO;
|
||||
} else if (IsXnu()) {
|
||||
sigenter = __sigenter_xnu;
|
||||
ap->sa_flags |= SA_SIGINFO; // couldn't hurt
|
||||
} else if (IsNetbsd()) {
|
||||
sigenter = __sigenter_netbsd;
|
||||
} else if (IsFreebsd()) {
|
||||
|
@ -231,7 +244,12 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
arg4 = 8; /* or linux whines */
|
||||
arg5 = 0;
|
||||
}
|
||||
if ((rc = sys_sigaction(sig, ap, oldact, arg4, arg5)) != -1) {
|
||||
if (!IsXnuSilicon()) {
|
||||
rc = sys_sigaction(sig, ap, oldact, arg4, arg5);
|
||||
} else {
|
||||
rc = _sysret(__syslib->__sigaction(sig, ap, oldact));
|
||||
}
|
||||
if (rc != -1) {
|
||||
sigaction_native2cosmo((union metasigaction *)oldact);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/ss.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
@ -82,9 +83,17 @@ static textwindows int sigaltstack_cosmo(const struct sigaltstack *neu,
|
|||
|
||||
static int sigaltstack_bsd(const struct sigaltstack *neu,
|
||||
struct sigaltstack *old) {
|
||||
int rc;
|
||||
struct sigaltstack_bsd oldbsd, neubsd, *neup = 0;
|
||||
if (neu) sigaltstack2bsd(&neubsd, neu), neup = &neubsd;
|
||||
if (sys_sigaltstack(neup, &oldbsd) == -1) return -1;
|
||||
if (IsXnuSilicon()) {
|
||||
rc = _sysret(__syslib->__sigaltstack(neup, &oldbsd));
|
||||
} else {
|
||||
rc = sys_sigaltstack(neup, &oldbsd);
|
||||
}
|
||||
if (rc == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (old) sigaltstack2linux(old, &oldbsd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -486,9 +486,14 @@ static privileged void linuxssefpustate2xnu(
|
|||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
#ifdef __x86_64__
|
||||
privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
#else
|
||||
privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
#endif
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wframe-larger-than="
|
||||
struct Goodies {
|
||||
|
@ -579,15 +584,6 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
: "=a"(ax)
|
||||
: "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle)
|
||||
: "rcx", "r11", "memory", "cc");
|
||||
#else
|
||||
register long r0 asm("x0") = (long)xnuctx;
|
||||
register long r1 asm("x1") = (long)infostyle;
|
||||
asm volatile("mov\tx16,%0\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(0x0b8 /* sigreturn */), "r"(r0), "r"(r1)
|
||||
: "x16", "memory");
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
notpossible;
|
||||
#endif /* __x86_64__ */
|
||||
}
|
||||
|
|
|
@ -17,32 +17,45 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps for particular number of seconds.
|
||||
*
|
||||
* This function may be canceled except when using masked mode in which
|
||||
* case cancelation is temporarily disabled, because there is no way to
|
||||
* report the ECANCELED state.
|
||||
*
|
||||
* @return 0 if the full time elapsed, otherwise we assume an interrupt
|
||||
* was delivered, in which case the errno condition is ignored, and
|
||||
* this function shall return the number of unslept seconds rounded
|
||||
* using the ceiling function, and finally `-1u` may be returned if
|
||||
* thread was cancelled with `PTHREAD_CANCEL_MASKED` in play
|
||||
* using the ceiling function
|
||||
* @see clock_nanosleep()
|
||||
* @cancelationpoint
|
||||
* @asyncsignalsafe
|
||||
* @norestart
|
||||
*/
|
||||
unsigned sleep(unsigned seconds) {
|
||||
errno_t rc;
|
||||
int cs = -1;
|
||||
errno_t err;
|
||||
unsigned unslept;
|
||||
struct timespec tv = {seconds};
|
||||
if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, &tv, &tv))) return 0;
|
||||
if (rc == ECANCELED) return -1u;
|
||||
npassert(rc == EINTR);
|
||||
if (_pthread_self()->pt_flags & PT_MASKED) {
|
||||
cs = _pthread_block_cancelation();
|
||||
}
|
||||
err = clock_nanosleep(CLOCK_REALTIME, 0, &tv, &tv);
|
||||
if (cs != -1) {
|
||||
_pthread_allow_cancelation(cs);
|
||||
}
|
||||
if (!err) return 0;
|
||||
unassert(err == EINTR);
|
||||
unslept = tv.tv_sec;
|
||||
if (tv.tv_nsec && unslept < UINT_MAX) {
|
||||
++unslept;
|
||||
|
|
|
@ -31,6 +31,12 @@ struct sigaction_netbsd {
|
|||
uint32_t sa_flags;
|
||||
};
|
||||
|
||||
struct sigaction_silicon {
|
||||
void *sa_handler;
|
||||
uint32_t sa_mask[1];
|
||||
uint32_t sa_flags;
|
||||
};
|
||||
|
||||
struct sigaction_xnu_in {
|
||||
void *sa_handler;
|
||||
void *sa_restorer;
|
||||
|
@ -50,6 +56,7 @@ union metasigaction {
|
|||
struct sigaction_freebsd freebsd;
|
||||
struct sigaction_openbsd openbsd;
|
||||
struct sigaction_netbsd netbsd;
|
||||
struct sigaction_silicon silicon;
|
||||
struct sigaction_xnu_in xnu_in;
|
||||
struct sigaction_xnu_out xnu_out;
|
||||
};
|
||||
|
|
|
@ -22,20 +22,31 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
|
||||
/**
|
||||
* Sleeps for specified delay.
|
||||
*
|
||||
* This function may be canceled except when using masked mode in which
|
||||
* case cancelation is temporarily disabled, because there is no way to
|
||||
* report the ECANCELED state.
|
||||
*
|
||||
* @return unslept time which may be non-zero if the call was interrupted
|
||||
* @cancelationpoint
|
||||
*/
|
||||
struct timespec timespec_sleep(struct timespec delay) {
|
||||
errno_t rc;
|
||||
int cs = -1;
|
||||
errno_t err;
|
||||
struct timespec remain;
|
||||
BLOCK_CANCELATION;
|
||||
bzero(&remain, sizeof(remain));
|
||||
if ((rc = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
|
||||
npassert(rc == EINTR);
|
||||
remain = timespec_zero;
|
||||
if (_pthread_self()->pt_flags & PT_MASKED) {
|
||||
cs = _pthread_block_cancelation();
|
||||
}
|
||||
if ((err = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
|
||||
unassert(err == EINTR);
|
||||
}
|
||||
if (cs != -1) {
|
||||
_pthread_allow_cancelation(cs);
|
||||
}
|
||||
ALLOW_CANCELATION;
|
||||
return remain;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,6 @@
|
|||
errno_t timespec_sleep_until(struct timespec abs_deadline) {
|
||||
errno_t rc;
|
||||
rc = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs_deadline, 0);
|
||||
npassert(!rc || rc == EINTR || rc == ECANCELED);
|
||||
unassert(!rc || rc == EINTR || rc == ECANCELED);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
@ -32,7 +33,9 @@
|
|||
* @norestart
|
||||
*/
|
||||
int usleep(uint32_t micros) {
|
||||
errno_t err;
|
||||
struct timespec ts = timespec_frommicros(micros);
|
||||
if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, 0)) return eintr();
|
||||
err = clock_nanosleep(CLOCK_REALTIME, 0, &ts, 0);
|
||||
if (err) return errno = err, -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue