Skip to content

Conversation

etcwilde
Copy link
Member

This improves the CPU core count handling for FreeBSD. This uses sysconf to grab the number of configured processors when logical and physical CPU counts are requested, and then pthread_getaffinity_np and the number of active processors. This takes into account the number of available cores when the process is restricted to a subset of the processors.

This also fixes the dispatch_workqueye test, which has its own implementation to extract the core count. FreeBSD does not have an hw.activecpu syscall, so the syscallbyname was failing and the activecpu count was garbage from the stack. I've updated the test to initialize the value with 0xa1a1a1 to make the garbage clearer. Also update the test for FreeBSD to take advantage of sysconf and pthread_getaffinity_np in the test.

Fixes: #897

@etcwilde
Copy link
Member Author

CC @kevans91

@etcwilde
Copy link
Member Author

@swift-ci please test

@etcwilde etcwilde moved this to In Progress in Swift on FreeBSD Aug 26, 2025
Copy link

@kevans91 kevans91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable, thanks!

This improves the CPU core count handling for FreeBSD. This uses sysconf
to grab the number of configured processors when logical and physical
CPU counts are requested, and then pthread_getaffinity_np and the number
of active processors. This takes into account the number of available
cores when the process is restricted to a subset of the processors.

This also fixes the `dispatch_workqueye` test, which has its own
implementation to extract the core count. FreeBSD does not have an
`hw.activecpu` syscall, so the syscallbyname was failing and the
activecpu count was garbage from the stack. I've updated the test to
initialize the value with `0xa1a1a1` to make the garbage clearer.
Also update the test for FreeBSD to take advantage of sysconf and
pthread_getaffinity_np in the test.

Fixes: swiftlang#897
@etcwilde etcwilde force-pushed the ewilde/freebsd-cpu-integration branch from 558886c to ea88133 Compare August 26, 2025 23:10
@etcwilde
Copy link
Member Author

@swift-ci please test

Copy link

@kevans91 kevans91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, for what that's worth. Happy to look a little bit closer if there's still something off with the test (I haven't tried to run it yet, personally).

@etcwilde
Copy link
Member Author

Thanks for your help. I’ve checked on my FreeBSD box, and all tests are passing with this change.

@etcwilde
Copy link
Member Author

@swift-ci please test Windows

@etcwilde etcwilde requested a review from rokhinip August 27, 2025 17:37
@al45tair
Copy link
Contributor

I'm assuming FreeBSD doesn't have anything like the problem Linux has with cgroups (namely, on Linux you can use cgroups to restrict the number of CPU cores available, but the usual ways of querying CPU core availability still report the number of cores on the system, not the number of cores set in the cgroup).

@github-project-automation github-project-automation bot moved this from In Progress to Merge in Swift on FreeBSD Aug 29, 2025
@kevans91
Copy link

kevans91 commented Aug 29, 2025

I'm assuming FreeBSD doesn't have anything like the problem Linux has with cgroups (namely, on Linux you can use cgroups to restrict the number of CPU cores available, but the usual ways of querying CPU core availability still report the number of cores on the system, not the number of cores set in the cgroup).

As in: sched_getaffinity/pthread_getafffinity_np won't report these restrictions either and you need cgroup-specific bits, or this is the reason for checking the affinity?

You can cpuset(8) away CPUs entirely per-process or per-jail without visibility to sysconf(3) or via a sysctl. If it's done at the jail level you're pretty much restricted to that subset, if it's per-process you have a chance of lifting the restriction.

It would be true on FreeBSD to say that the current implementation of _dispatch_hw_config_logical_cpus and _dispatch_hw_config_physical_cpus may be inaccurate if you're in a jail that has a more limited root set because you wouldn't be able to cpuset_setaffinity(2) your way up to the currently reported values -- you would need to grab your root cpuset id and check the affinity of that to understand the most a process has available to it beyond what's currently configured.

I don't think it's a problem that FreeBSD couldn't fix, but it is a little awkward to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Merge
Development

Successfully merging this pull request may close these issues.

FreeBSD: Test Failed: dispatch_workqueue
3 participants