Skip to content

implement cpuset_getaffinity for freebsd #4287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

LorrensP-2158466
Copy link
Contributor

@LorrensP-2158466 LorrensP-2158466 commented Apr 22, 2025

Fixes #4265.

This implements the FreeBSD syscall cpuset_getaffinity. In practice, this syscall behaves like a more fine-grained api than sched_getaffinity.

The tests only require one specific combination of parameters to pass, so this is all that is implemented. This can be done in future work (or now if needed).

However, I had to change 1 test file available-parallelism-miri-num-cpus. This test sets the number of CPUs to 1024, but the libc API is structured so that only 256 can be accepted. (I'll explain in a comment.)

I have not changed the ci script since I don't know what I should put there.

@LorrensP-2158466
Copy link
Contributor Author

So the tests use the libc function libc::CPU_COUNT, which counts how many bits are flipped to 1 in the cpuset. The source code that calls the syscall uses the struct libc::cpuset_t, and the size of this set struct is used to write the specified bytes to the mask pointer.

The source of this struct is this:

pub struct cpuset_t {
    #[cfg(all(any(freebsd15, freebsd14), target_pointer_width = "64"))]
    __bits: [c_long; 16],
    #[cfg(all(any(freebsd15, freebsd14), target_pointer_width = "32"))]
    __bits: [c_long; 32],
    #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "64"))]
    __bits: [c_long; 4],
    #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "32"))]
    __bits: [c_long; 8],
}

So on newer FreeBSD version, this struct is 128 bytes large, otherwise 32 bytes. During testing I have found out that the current compilation results in the 32 bytes variant. This means we can only "use" 256 CPUs since the size of the mask is: 32 * 8 = 256. Miri's maximum number is 1024 and the test also sets and expects this value.

I have no idea how to alter compilation to use the 128 size variant, which would result in 1024 bits being used. But the test passes when using -Zmiri-num-cpus=256.

@LorrensP-2158466
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Apr 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Waiting for a review to complete
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support num_cpus on FreeBSD
2 participants