From af1af5d2cb33fcebf188129e1279f15c83a41aa7 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 20 Mar 2026 10:42:37 +1100 Subject: [PATCH 1/4] swift_timer: fix dispatch source lifecycle bugs - Save timer type in swifthal_timer_start so oneshot cancellation works - Call dispatch_resume in swifthal_timer_start so the timer actually fires - Resume the source in swifthal_timer_close before releasing to avoid crashing when releasing a suspended dispatch source Amp-Thread-ID: https://ampcode.com/threads/T-019d0869-5a22-779b-b3d6-76212f36411e Co-authored-by: Amp --- Sources/LinuxHalSwiftIO/swift_timer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/LinuxHalSwiftIO/swift_timer.c b/Sources/LinuxHalSwiftIO/swift_timer.c index 011ffe1..8077dcc 100644 --- a/Sources/LinuxHalSwiftIO/swift_timer.c +++ b/Sources/LinuxHalSwiftIO/swift_timer.c @@ -52,6 +52,7 @@ int swifthal_timer_close(void *arg) { if (timer) { dispatch_source_cancel(timer->source); + dispatch_resume(timer->source); dispatch_release(timer->source); free(timer); return 0; @@ -61,15 +62,17 @@ int swifthal_timer_close(void *arg) { } int swifthal_timer_start(void *arg, swift_timer_type_t type, ssize_t period) { - const struct swifthal_timer *timer = arg; + struct swifthal_timer *timer = arg; if (timer) { uint64_t interval = (uint64_t)period * NSEC_PER_MSEC; + timer->type = type; dispatch_source_set_timer( timer->source, dispatch_time(DISPATCH_TIME_NOW, interval), (type == SWIFT_TIMER_TYPE_ONESHOT) ? DISPATCH_TIME_FOREVER : interval, 0); + dispatch_resume(timer->source); return 0; } From 0c915e1fb47f7ba51309aad351c6d3f14ac9a599 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 20 Mar 2026 10:44:20 +1100 Subject: [PATCH 2/4] swift_fs: fix fread/fwrite size/nmemb argument order fwrite(buf, size, 1) and fread(buf, size, 1) return 1 on success rather than the actual byte count, and partial reads are silently lost. Swap to fwrite(buf, 1, size) and fread(buf, 1, size) so the return value reflects the actual number of bytes transferred. Amp-Thread-ID: https://ampcode.com/threads/T-019d0869-5a22-779b-b3d6-76212f36411e Co-authored-by: Amp --- Sources/LinuxHalSwiftIO/swift_fs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/LinuxHalSwiftIO/swift_fs.c b/Sources/LinuxHalSwiftIO/swift_fs.c index be3afef..cbde714 100644 --- a/Sources/LinuxHalSwiftIO/swift_fs.c +++ b/Sources/LinuxHalSwiftIO/swift_fs.c @@ -92,8 +92,8 @@ int swifthal_fs_rename(const char *from, char *to) { int swifthal_fs_write(void *fp, const void *buf, ssize_t size) { size_t nbytes; - nbytes = fwrite(buf, size, 1, fp); - if (nbytes != 1) { + nbytes = fwrite(buf, 1, size, fp); + if (nbytes == 0) { if (ferror(fp)) return -errno; return -EIO; @@ -105,8 +105,8 @@ int swifthal_fs_write(void *fp, const void *buf, ssize_t size) { int swifthal_fs_read(void *fp, void *buf, ssize_t size) { size_t nbytes; - nbytes = fread(buf, size, 1, fp); - if (nbytes != 1) { + nbytes = fread(buf, 1, size, fp); + if (nbytes == 0) { if (ferror(fp)) return -errno; if (feof(fp)) From 1f7dd5b61086c047e26632d3cbbdcb74996b9624 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 20 Mar 2026 10:44:28 +1100 Subject: [PATCH 3/4] swift_os: fix thread leak, timed wait, and semaphore reset bugs - Create threads detached so resources are reclaimed on exit - swifthal_timeout_to_timespec now computes an absolute CLOCK_REALTIME deadline as required by mq_timedsend, mq_timedreceive, sem_timedwait, and pthread_mutex_timedlock (previously used a relative time which caused all timed waits to expire immediately) - swifthal_os_sem_reset: handle EAGAIN from sem_trywait gracefully instead of treating a concurrent race as a fatal error Amp-Thread-ID: https://ampcode.com/threads/T-019d0869-5a22-779b-b3d6-76212f36411e Co-authored-by: Amp --- Sources/LinuxHalSwiftIO/swift_os.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Sources/LinuxHalSwiftIO/swift_os.c b/Sources/LinuxHalSwiftIO/swift_os.c index e55120d..be50481 100644 --- a/Sources/LinuxHalSwiftIO/swift_os.c +++ b/Sources/LinuxHalSwiftIO/swift_os.c @@ -69,6 +69,8 @@ void *swifthal_os_task_create(char *name, task->p3 = p3; err = pthread_attr_init(&attr); + if (err == 0) + err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (err == 0) err = pthread_attr_getschedparam(&attr, ¶m); if (err == 0) { @@ -151,8 +153,13 @@ static struct timespec *swifthal_timeout_to_timespec(int timeout, if (timeout == -1) return NULL; - ts->tv_sec = timeout / 1000; - ts->tv_nsec = (timeout % 1000) * NSEC_PER_MSEC; + clock_gettime(CLOCK_REALTIME, ts); + ts->tv_sec += timeout / 1000; + ts->tv_nsec += (timeout % 1000) * NSEC_PER_MSEC; + if (ts->tv_nsec >= 1000000000L) { + ts->tv_sec += ts->tv_nsec / 1000000000L; + ts->tv_nsec %= 1000000000L; + } return ts; } @@ -367,7 +374,12 @@ int swifthal_os_sem_reset(const void *arg) { if (sem_getvalue(&sem->sem, &value) != 0) return -errno; while (value > sem->init_cnt) { - if (sem_trywait(&sem->sem) != 0 || sem_getvalue(&sem->sem, &value) != 0) + if (sem_trywait(&sem->sem) != 0) { + if (errno == EAGAIN) + break; + return -errno; + } + if (sem_getvalue(&sem->sem, &value) != 0) return -errno; } From 52a47eb81d868c1f0e1cadd7604db5db9b64a46b Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 20 Mar 2026 10:44:33 +1100 Subject: [PATCH 4/4] swift_platform: fix hwcycle_get truncation and hwcycle_to_ns - swifthal_hwcycle_get on x86: return only the low 32 bits (a) instead of constructing a 64-bit value that gets silently truncated - swifthal_hwcycle_to_ns: use clock_getres(CLOCK_MONOTONIC) to compute a meaningful cycle-to-nanosecond conversion instead of returning the unrelated sysconf(_SC_CLK_TCK) value Amp-Thread-ID: https://ampcode.com/threads/T-019d0869-5a22-779b-b3d6-76212f36411e Co-authored-by: Amp --- Sources/LinuxHalSwiftIO/swift_platform.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/LinuxHalSwiftIO/swift_platform.c b/Sources/LinuxHalSwiftIO/swift_platform.c index bf63b5a..59e786c 100644 --- a/Sources/LinuxHalSwiftIO/swift_platform.c +++ b/Sources/LinuxHalSwiftIO/swift_platform.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #ifdef __linux__ #include @@ -46,7 +47,7 @@ uint32_t swifthal_hwcycle_get(void) { #if __x86_64__ unsigned a, d; asm volatile("rdtsc" : "=a"(a), "=d"(d)); - return ((uint64_t)a) | (((uint64_t)d) << 32); + return a; #elif defined(__aarch64__) uint64_t val; asm volatile("mrs %0, cntvct_el0" : "=r"(val)); @@ -61,7 +62,10 @@ uint32_t swifthal_hwcycle_get(void) { } uint32_t swifthal_hwcycle_to_ns(unsigned int cycles) { - return (uint32_t)sysconf(_SC_CLK_TCK); + struct timespec tp; + if (clock_getres(CLOCK_MONOTONIC, &tp) < 0) + return 0; + return (uint32_t)((uint64_t)cycles * (tp.tv_sec * 1000000000ULL + tp.tv_nsec)); } void swiftHal_randomGet(uint8_t *buf, ssize_t length) {