On Thu, 24 Sep 2026 16:40:34 +0200, Stuart Henderson <[email protected]> wrote: > > On 2026/09/23 18:49, Brad Smith wrote: > > On Tue, Sep 22, 2026 at 09:17:19PM +0100, Stuart Henderson wrote: > > > On 2026/09/22 21:04, Kirill A. Korinsky wrote: > > > > Well, check-shlib-syms states that here no difference... probably > > > > SHARED_LIBS really doesn't need a bump. > > > > > > it seemed that way to me (and I was quite happy to get rid of all those > > > patches!). > > > > > > > Anyway, here a diff which a bit hacky and fixes regression in tdesktop > > > > and > > > > 64gram, and I think in other similar places. > > > > > > > Thoughts? > > > > > > thanks, that makes sense. ok. > > > > This looks like a more appropraite fix. > > > > > > Index: Makefile > > =================================================================== > > RCS file: /cvs/ports/devel/libdispatch/Makefile,v > > retrieving revision 1.13 > > diff -u -p -u -p -r1.13 Makefile > > --- Makefile 22 Sep 2026 20:26:42 -0000 1.13 > > +++ Makefile 23 Sep 2026 22:24:43 -0000 > > @@ -2,7 +2,7 @@ COMMENT = support for concurrent code ex > > > > PKGNAME = libdispatch-$V > > V = 6.4.0 > > -REVISION = 0 > > +REVISION = 1 > > > > GH_ACCOUNT = apple > > GH_PROJECT = swift-corelibs-libdispatch > > Index: patches/patch-src_event_event_config_h > > =================================================================== > > RCS file: patches/patch-src_event_event_config_h > > diff -N patches/patch-src_event_event_config_h > > --- patches/patch-src_event_event_config_h 22 Sep 2026 20:26:42 -0000 > > 1.1 > > +++ /dev/null 1 Jan 1970 00:00:00 -0000 > > @@ -1,18 +0,0 @@ > > -https://github.com/swiftlang/swift-corelibs-libdispatch/pull/960 > > - > > -Index: src/event/event_config.h > > ---- src/event/event_config.h.orig > > -+++ src/event/event_config.h > > -@@ -116,9 +116,10 @@ > > - # define NOTE_FUNLOCK 0x00000100 > > - # endif > > - > > --// FreeBSD's kevent does not support those > > -+// FreeBSD's and OpenBSD's kevent does not support those > > -+// OpenBSD's NOTE_ABSTIME uses CLOCK_REALTIME > > - # ifndef NOTE_ABSOLUTE > > --# ifdef NOTE_ABSTIME > > -+# if defined(NOTE_ABSTIME) && !defined(__OpenBSD__) > > - # define NOTE_ABSOLUTE NOTE_ABSTIME > > - # else > > - # define NOTE_ABSOLUTE 0 > > Index: patches/patch-src_event_event_kevent_c > > =================================================================== > > RCS file: patches/patch-src_event_event_kevent_c > > diff -N patches/patch-src_event_event_kevent_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-src_event_event_kevent_c 23 Sep 2026 22:24:43 -0000 > > @@ -0,0 +1,41 @@ > > +- Use relative kqueue deadlines for BSD uptime and monotonic timers > > + https://github.com/swiftlang/swift-corelibs-libdispatch/pull/943 > > + > > +Index: src/event/event_kevent.c > > +--- src/event/event_kevent.c.orig > > ++++ src/event/event_kevent.c > > +@@ -60,10 +60,22 @@ DISPATCH_STATIC_GLOBAL(struct dispatch_muxnote_bucket_ > > + #define DISPATCH_NOTE_CLOCK_UPTIME 0 > > + #endif > > + > > ++#if defined(__FreeBSD__) || defined(__OpenBSD__) > > ++// BSD NOTE_ABSTIME deadlines use CLOCK_REALTIME. > > ++#define DISPATCH_NOTE_ABSOLUTE_WALL NOTE_ABSOLUTE > > ++#define DISPATCH_NOTE_ABSOLUTE_MONOTONIC 0 > > ++#define DISPATCH_NOTE_ABSOLUTE_UPTIME 0 > > ++#else > > ++#define DISPATCH_NOTE_ABSOLUTE_WALL NOTE_ABSOLUTE > > ++#define DISPATCH_NOTE_ABSOLUTE_MONOTONIC NOTE_ABSOLUTE > > ++#define DISPATCH_NOTE_ABSOLUTE_UPTIME NOTE_ABSOLUTE > > ++#endif > > ++ > > + static const uint32_t _dispatch_timer_index_to_fflags[] = { > > + #define DISPATCH_TIMER_FFLAGS_INIT(kind, qos, note) \ > > + [DISPATCH_TIMER_INDEX(DISPATCH_CLOCK_##kind, DISPATCH_TIMER_QOS_##qos)] > > = \ > > +- DISPATCH_NOTE_CLOCK_##kind | NOTE_ABSOLUTE | > > NOTE_LEEWAY | (note) > > ++ DISPATCH_NOTE_CLOCK_##kind | DISPATCH_NOTE_ABSOLUTE_##kind | \ > > ++ NOTE_LEEWAY | (note) > > + DISPATCH_TIMER_FFLAGS_INIT(WALL, NORMAL, 0), > > + DISPATCH_TIMER_FFLAGS_INIT(UPTIME, NORMAL, 0), > > + DISPATCH_TIMER_FFLAGS_INIT(MONOTONIC, NORMAL, 0), > > +@@ -2406,6 +2418,10 @@ > > _dispatch_event_loop_timer_arm(dispatch_timer_heap_t d > > + } > > + #if !NOTE_ABSOLUTE > > + target = range.delay; > > ++#elif defined(__FreeBSD__) || defined(__OpenBSD__) > > ++ if (clock != DISPATCH_CLOCK_WALL) { > > ++ target -= _dispatch_time_now_cached(clock, nows); > > ++ } > > + #endif > > + > > + _dispatch_event_loop_timer_program(dth, tidx, target, range.leeway, > > Index: patches/patch-tests_CMakeLists_txt > > =================================================================== > > RCS file: patches/patch-tests_CMakeLists_txt > > diff -N patches/patch-tests_CMakeLists_txt > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-tests_CMakeLists_txt 23 Sep 2026 22:24:43 -0000 > > @@ -0,0 +1,17 @@ > > +- Use relative kqueue deadlines for BSD uptime and monotonic timers > > + https://github.com/swiftlang/swift-corelibs-libdispatch/pull/943 > > + > > +Index: tests/CMakeLists.txt > > +--- tests/CMakeLists.txt.orig > > ++++ tests/CMakeLists.txt > > +@@ -140,6 +140,10 @@ set(DISPATCH_C_TESTS > > + io_pipe_close > > + select) > > + > > ++if(UNIX) > > ++ list(APPEND DISPATCH_C_TESTS timer_idle) > > ++endif() > > ++ > > + # Tests that usually pass, but occasionally fail. > > + # Excluded by default for purposes of Swift CI > > + if(EXTENDED_TEST_SUITE) > > Index: patches/patch-tests_dispatch_timer_idle_c > > =================================================================== > > RCS file: patches/patch-tests_dispatch_timer_idle_c > > diff -N patches/patch-tests_dispatch_timer_idle_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-tests_dispatch_timer_idle_c 23 Sep 2026 22:24:43 > > -0000 > > @@ -0,0 +1,157 @@ > > +- Use relative kqueue deadlines for BSD uptime and monotonic timers > > + https://github.com/swiftlang/swift-corelibs-libdispatch/pull/943 > > + > > +Index: tests/dispatch_timer_idle.c > > +--- tests/dispatch_timer_idle.c.orig > > ++++ tests/dispatch_timer_idle.c > > +@@ -0,0 +1,150 @@ > > ++/* > > ++ * This source file is part of the Swift.org open source project > > ++ * > > ++ * Copyright (c) 2026 Apple Inc. and the Swift project authors > > ++ * > > ++ * Licensed under Apache License v2.0 with Runtime Library Exception > > ++ * > > ++ * See https://swift.org/LICENSE.txt for license information > > ++ * See https://swift.org/CONTRIBUTORS.txt for the list of Swift project > > authors > > ++ * > > ++ */ > > ++ > > ++#include <dispatch/dispatch.h> > > ++ > > ++#include <bsdtests.h> > > ++#include "dispatch_test.h" > > ++ > > ++#include <errno.h> > > ++#include <stdatomic.h> > > ++#include <stdint.h> > > ++#include <stdio.h> > > ++#include <stdlib.h> > > ++#include <sys/resource.h> > > ++#include <time.h> > > ++ > > ++#define OBSERVATION_SECONDS 0.25 > > ++#define MAX_IDLE_CPU_RATIO 0.20 > > ++ > > ++static _Atomic int timer_fired; > > ++static volatile uint64_t spin_sink; > > ++ > > ++static void > > ++monotonic_now(struct timespec *value) > > ++{ > > ++ if (clock_gettime(CLOCK_MONOTONIC, value) != 0) { > > ++ perror("clock_gettime"); > > ++ exit(EXIT_FAILURE); > > ++ } > > ++} > > ++ > > ++static double > > ++seconds_between(struct timespec start, struct timespec end) > > ++{ > > ++ return (double)(end.tv_sec - start.tv_sec) + > > ++ (double)(end.tv_nsec - start.tv_nsec) / (double)NSEC_PER_SEC; > > ++} > > ++ > > ++static double > > ++timeval_seconds(struct timeval value) > > ++{ > > ++ return (double)value.tv_sec + > > ++ (double)value.tv_usec / (double)USEC_PER_SEC; > > ++} > > ++ > > ++static double > > ++process_cpu_seconds(void) > > ++{ > > ++ struct rusage usage; > > ++ > > ++ if (getrusage(RUSAGE_SELF, &usage) != 0) { > > ++ perror("getrusage"); > > ++ exit(EXIT_FAILURE); > > ++ } > > ++ return timeval_seconds(usage.ru_utime) + > > timeval_seconds(usage.ru_stime); > > ++} > > ++ > > ++static double > > ++measure_busy_cpu_ratio(void) > > ++{ > > ++ struct timespec wall_start, wall_now; > > ++ double cpu_start, cpu_end; > > ++ > > ++ monotonic_now(&wall_start); > > ++ cpu_start = process_cpu_seconds(); > > ++ do { > > ++ spin_sink++; > > ++ monotonic_now(&wall_now); > > ++ } while (seconds_between(wall_start, wall_now) < OBSERVATION_SECONDS); > > ++ cpu_end = process_cpu_seconds(); > > ++ > > ++ return (cpu_end - cpu_start) / seconds_between(wall_start, wall_now); > > ++} > > ++ > > ++static void > > ++unexpected_timer_fire(void *context) > > ++{ > > ++ (void)context; > > ++ atomic_store_explicit(&timer_fired, 1, memory_order_relaxed); > > ++} > > ++ > > ++static void > > ++observe_idle_timer(double *wall_seconds, double *cpu_seconds) > > ++{ > > ++ struct timespec wall_start, wall_end; > > ++ struct timespec remaining = { > > ++ .tv_sec = 0, > > ++ .tv_nsec = (long)(OBSERVATION_SECONDS * (double)NSEC_PER_SEC), > > ++ }; > > ++ dispatch_source_t timer; > > ++ double cpu_start; > > ++ int sleep_result; > > ++ > > ++ timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, > > ++ > > dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); > > ++ test_ptr_notnull("dispatch_source_create", timer); > > ++ dispatch_source_set_event_handler_f(timer, unexpected_timer_fire); > > ++ dispatch_source_set_timer(timer, > > ++ dispatch_time(DISPATCH_TIME_NOW, 3600 * NSEC_PER_SEC), > > ++ DISPATCH_TIME_FOREVER, 0); > > ++ dispatch_resume(timer); > > ++ > > ++ monotonic_now(&wall_start); > > ++ cpu_start = process_cpu_seconds(); > > ++ do { > > ++ sleep_result = nanosleep(&remaining, &remaining); > > ++ } while (sleep_result == -1 && errno == EINTR); > > ++ if (sleep_result != 0) { > > ++ perror("nanosleep"); > > ++ exit(EXIT_FAILURE); > > ++ } > > ++ *cpu_seconds = process_cpu_seconds() - cpu_start; > > ++ monotonic_now(&wall_end); > > ++ *wall_seconds = seconds_between(wall_start, wall_end); > > ++ > > ++ dispatch_source_cancel(timer); > > ++ dispatch_release(timer); > > ++} > > ++ > > ++int > > ++main(void) > > ++{ > > ++ double busy_cpu_ratio, idle_wall_seconds, idle_cpu_seconds; > > ++ double idle_cpu_ratio, relative_cpu_ratio; > > ++ > > ++ dispatch_test_start("Dispatch idle timer CPU usage"); > > ++ > > ++ busy_cpu_ratio = measure_busy_cpu_ratio(); > > ++ observe_idle_timer(&idle_wall_seconds, &idle_cpu_seconds); > > ++ idle_cpu_ratio = idle_cpu_seconds / idle_wall_seconds; > > ++ relative_cpu_ratio = idle_cpu_ratio / busy_cpu_ratio; > > ++ > > ++ fprintf(stderr, "idle=%f busy=%f relative=%f\n", > > ++ idle_cpu_ratio, busy_cpu_ratio, relative_cpu_ratio); > > ++ test_long("timer fired", atomic_load_explicit(&timer_fired, > > ++ memory_order_relaxed), 0); > > ++ test_double_less_than("idle timer CPU ratio", relative_cpu_ratio, > > ++ MAX_IDLE_CPU_RATIO); > > ++ test_stop(); > > ++ return 0; > > ++} > > > > asterisk looks ok, cpu use with Telegram is looking reasonably sane > once it's settled down after startup. Kirill, does it seem ok for you > too? >
Yes, it reads OK and looks better, but I haven't tested it. Anyway, in case of telegram CPU usage was near instant and easy to catch. -- wbr, Kirill
